From d54cb706a4092bcd51517ec1823cb0f3a39762f9 Mon Sep 17 00:00:00 2001 From: John Goerzen Date: Fri, 17 Nov 2006 19:55:15 +0000 Subject: [PATCH] Imported gpsbabel-1.3.2 into Darcs repository --- AUTHORS | 58 + ChangeLog | 17 - Makefile | 366 - Makefile.in | 784 + README | 1416 -- README.contrib | 64 +- an1.c | 535 +- an1sym.h | 4 +- arcdist.c | 62 +- axim_gpb.c | 182 + bcr.c | 297 +- brauniger_iq.c | 278 +- cet.c | 360 + cet.h | 71 + cet/ansi_x3_4_1968.h | 305 + cet/atarist.h | 256 + cet/baltic.h | 178 + cet/bs_4730.h | 127 + cet/bs_viewdata.h | 134 + cet/cp1250.h | 203 + cet/cp1251.h | 241 + cet/cp1252.h | 156 + cet/cp1253.h | 219 + cet/cp1254.h | 163 + cet/cp1255.h | 180 + cet/cp1256.h | 210 + cet/cp1257.h | 198 + cet/csa_z243_4_1985_1.h | 131 + cet/csa_z243_4_1985_2.h | 131 + cet/csa_z243_4_1985_gr.h | 206 + cet/csn_369103.h | 200 + cet/cwi.h | 256 + cet/dec_mcs.h | 129 + cet/din_66003.h | 129 + cet/ds_2089.h | 124 + cet/ecma_cyrillic.h | 219 + cet/es.h | 132 + cet/es2.h | 129 + cet/gb_1988_80.h | 127 + cet/gost_19768_87.h | 189 + cet/hp_roman8.h | 219 + cet/ibm037.h | 381 + cet/ibm1004.h | 152 + cet/ibm1026.h | 380 + cet/ibm1047.h | 380 + cet/ibm256.h | 381 + cet/ibm273.h | 380 + cet/ibm277.h | 380 + cet/ibm278.h | 381 + cet/ibm280.h | 381 + cet/ibm284.h | 381 + cet/ibm285.h | 381 + cet/ibm297.h | 381 + cet/ibm437.h | 256 + cet/ibm500.h | 381 + cet/ibm850.h | 257 + cet/ibm851.h | 255 + cet/ibm852.h | 257 + cet/ibm855.h | 255 + cet/ibm857.h | 252 + cet/ibm860.h | 256 + cet/ibm861.h | 256 + cet/ibm862.h | 255 + cet/ibm863.h | 256 + cet/ibm864.h | 249 + cet/ibm865.h | 256 + cet/ibm868.h | 232 + cet/ibm869.h | 248 + cet/ibm871.h | 381 + cet/ibm891.h | 108 + cet/ibm903.h | 108 + cet/ibm904.h | 131 + cet/iec_p27_1.h | 220 + cet/iso_10367_box.h | 149 + cet/iso_5427.h | 188 + cet/iso_646_irv.h | 127 + cet/iso_6937_2_25.h | 166 + cet/iso_8859_1.h | 111 + cet/iso_8859_10.h | 172 + cet/iso_8859_13.h | 175 + cet/iso_8859_14.h | 157 + cet/iso_8859_15.h | 133 + cet/iso_8859_2.h | 183 + cet/iso_8859_3.h | 154 + cet/iso_8859_4.h | 176 + cet/iso_8859_5.h | 219 + cet/iso_8859_6.h | 173 + cet/iso_8859_7.h | 199 + cet/iso_8859_8.h | 156 + cet/iso_8859_9.h | 129 + cet/iso_8859_supp.h | 212 + cet/it.h | 134 + cet/jis_c6220_1969_ro.h | 120 + cet/jis_x0201.h | 195 + cet/jus_i_b1_002.h | 131 + cet/jus_i_b1_003_mac.h | 182 + cet/jus_i_b1_003_serb.h | 182 + cet/keybcs2.h | 256 + cet/koi8_r.h | 256 + cet/koi8_ru.h | 256 + cet/koi8_u.h | 238 + cet/koi_7.h | 156 + cet/koi_8.h | 191 + cet/koi_8_cs2.h | 222 + cet/ksc5636.h | 118 + cet/latin_greek_1.h | 136 + cet/mac_is.h | 248 + cet/macintosh.h | 250 + cet/macintosh_ce.h | 254 + cet/msz_7795_3.h | 135 + cet/nats_dano.h | 136 + cet/nats_sefi.h | 130 + cet/nc_nc00_10.h | 133 + cet/nextstep.h | 240 + cet/nf_z_62_010.h | 135 + cet/nf_z_62_010__1973_.h | 133 + cet/ns_4551_1.h | 125 + cet/ns_4551_2.h | 133 + cet/pt.h | 128 + cet/pt2.h | 127 + cet/sami.h | 157 + cet/sen_850200_b.h | 133 + cet/sen_850200_c.h | 136 + cet/tcvn.h | 278 + cet/viscii.h | 247 + cet/vps.h | 255 + cet_util.c | 1262 ++ cet_util.h | 133 + cetus.c | 36 +- chkdoc | 9 +- coastexp.c | 65 +- coldsync/Makefile | 38 - coldsync/Makefile.in | 0 coldsync/{config.h => cs-config.h} | 0 coldsync/palm.h | 12 +- coldsync/pdb.c | 87 +- coldsync/util.c | 5 +- compegps.c | 663 + config.guess | 1463 ++ config.h.in | 59 + config.sub | 1579 ++ configure | 4603 +++++ configure.in | 278 + copilot.c | 22 +- coto.c | 278 +- cst.c | 362 + csv_util.c | 227 +- csv_util.h | 15 +- defs.h | 340 +- delgpl.c | 43 +- discard.c | 107 +- dmtlog.c | 719 + duplicate.c | 33 +- easygps.c | 32 +- fatal.c | 41 + filter_skeleton.c | 42 +- filter_vecs.c | 167 +- filterdefs.h | 46 + format_skeleton.c | 156 + formspec.c | 2 + garmin.c | 263 +- garmin_fs.c | 308 + garmin_fs.h | 124 + garmin_tables.c | 593 +- garmin_tables.h | 71 +- garmin_txt.c | 1272 ++ gbfile.c | 667 + gbfile.h | 95 + gbser.c | 181 + gbser.h | 137 + gbser_posix.c | 424 + gbser_private.h | 27 + gbser_win.c | 429 + gbsleep.c | 51 + gbtypes.h | 10 +- gcdb.c | 10 +- gdb.c | 622 +- geo.c | 41 +- geoniche.c | 374 +- globals.c | 29 + glogbook.c | 26 +- google.c | 196 +- gpilots.c | 21 +- gpsbabel-sample.ini | 35 + gpsbabel.html | 4371 +++++ gpspilot.c | 13 +- gpssim.c | 206 + gpsutil.c | 69 +- gpx.c | 624 +- grtcirc.c | 157 +- grtcirc.h | 22 +- gtm.c | 769 + gtrnctr.c | 306 + guibabel | 2 +- hiketech.c | 16 +- holux.c | 40 +- hsa_ndv.c | 111 +- html.c | 148 +- igc.c | 71 +- ignrando.c | 318 + inifile.c | 351 + inifile.h | 62 + install-sh | 323 + intdoc/SA2003_an1_dump.pl | 78 +- intdoc/SA2003_annotations.txt | 2 +- intdoc/an1_road_types.txt | 52 + intdoc/jeeps-device.odg | Bin 0 -> 9852 bytes internal_styles.c | 381 +- interpolate.c | 194 + jeeps/Makefile.in | 0 jeeps/garminusb.h | 18 +- jeeps/gps.h | 45 +- jeeps/gpsapp.c | 913 +- jeeps/gpsapp.h | 15 +- jeeps/gpscom.c | 53 +- jeeps/gpscom.h | 8 +- jeeps/gpsdatum.h | 2 +- jeeps/gpsdevice.c | 86 + jeeps/gpsdevice.h | 73 + jeeps/gpsdevice_ser.c | 37 + jeeps/gpsdevice_usb.c | 59 + jeeps/gpslibusb.c | 333 +- jeeps/gpsmath.c | 25 +- jeeps/gpsmath.h | 2 + jeeps/gpsmem.c | 1192 +- jeeps/gpsmem.h | 61 - jeeps/gpsnmea.h | 312 - jeeps/gpsnmeafmt.h | 44 - jeeps/gpsnmeaget.h | 43 - jeeps/gpsprot.c | 3 +- jeeps/gpsprot.h | 52 +- jeeps/gpsread.c | 31 +- jeeps/gpsread.h | 8 +- jeeps/gpsrqst.c | 13 +- jeeps/gpsrqst.h | 4 +- jeeps/gpssend.c | 21 +- jeeps/gpssend.h | 7 +- jeeps/gpsserial.c | 390 +- jeeps/gpsserial.h | 30 +- jeeps/gpsusbcommon.c | 268 + jeeps/gpsusbcommon.h | 45 + jeeps/gpsusbint.h | 6 +- jeeps/gpsusbread.c | 47 +- jeeps/gpsusbsend.c | 7 +- jeeps/gpsusbstub.c | 34 +- jeeps/gpsusbwin.c | 338 +- jeeps/gpsutil.c | 26 +- jeeps/gpsutil.h | 5 +- kml.c | 822 +- lowranceusr.c | 78 +- .../English.lproj/MainMenu.nib/info.nib | 13 +- .../English.lproj/MainMenu.nib/objects.nib | Bin 22092 -> 27700 bytes macgpsbabel/Info.plist | 28 + macgpsbabel/MacGPSBabel.applescript | 15 +- .../MacGPSBabel.xcodeproj/project.pbxproj | 400 + mag_pdb.c | 243 + maggeo.c | 59 +- magnav.c | 14 +- magproto.c | 619 +- main.c | 319 +- make-an1sym.pl | 4 +- mapopolis.c | 13 +- mapsend.c | 88 +- mapsource.c | 341 +- mingw/Makefile | 5 +- mingw/libw/README | 1 + mingw/libw/libexpat.a | Bin 0 -> 51328 bytes mingw/mkwintesto.c | 30 +- mingw/wintesto.cmd | 450 +- mkicondoc.c | 67 + mkshort.c | 219 +- mkstyle.sh | 9 +- msroute.c | 675 + msvc/Debug.empty | 0 msvc/Expatw/expat.h | 1013 ++ msvc/Expatw/expat_external.h | 115 + msvc/Expatw/libexpatw.dll | Bin 0 -> 151552 bytes msvc/Expatw/libexpatw.lib | Bin 0 -> 17544 bytes msvc/GPSBabel.dsp | 4 + msvc/GPSBabel.sln | 43 +- msvc/GPSBabel.vcproj | 5018 +++-- msvc/README.msvc | 5 + msvc/Unicode.empty | 0 msvc/build.bat | 9 + msvc/config.h | 28 + msvc/release.empty | 0 navicache.c | 31 +- netstumbler.c | 56 +- nmea.c | 673 +- nmn4.c | 322 + nukedata.c | 64 + overlay.c | 43 +- ozi.c | 194 +- palmdoc.c | 61 +- pathaway.c | 213 +- pcx.c | 211 +- polygon.c | 134 +- position.c | 212 +- psitrex.c | 33 +- psp.c | 36 +- queue.c | 159 + queue.h | 14 +- quovadis.c | 15 +- radius.c | 223 + reference/an1-an1.ref | Bin 2958 -> 3556 bytes reference/an1-out.ref | Bin 280 -> 326 bytes reference/cet/cet-sample.cp1250.txt | 17 + reference/cet/cet-sample.gdb | Bin 0 -> 1919 bytes reference/cet/cet-sample.gpx | 122 + reference/cet/cet-sample.latin1.txt | 17 + reference/cet/cet-sample.latin2.txt | 17 + reference/cet/cet-sample.macroman.txt | 17 + reference/coastexp.ref | 4 +- reference/coastexp.ref3 | 2 +- reference/compegps-wpt.gpx | 178 + reference/compegps.wpt | 52 + reference/compegps.wpt.gz | Bin 0 -> 967 bytes reference/cototestmarker.gpx | 8 +- reference/cototesttrack.csv | 270 +- reference/dusky.gnuplot | 126 +- reference/earth-expertgps.kml | 3373 ++++ reference/earth-gc.kml | 139 + reference/garmin_txt.txt | 96 + reference/gc/maggeo.gs | 3 + reference/gdb-sample.gdb | Bin 122965 -> 66829 bytes reference/gdb-sample.gpx | 15118 +++------------- reference/gdb-sample2.gdb | Bin 0 -> 6314 bytes reference/geonet-sample.gpx | 55 + reference/geonet-sample.txt | 10 + reference/gn-targets.gpx | 34 + reference/gn-targets.pdb | Bin 0 -> 586 bytes reference/google.csv | 111 + reference/google_jan_06.csv | 111 + reference/google_jan_06.html | 2 + reference/hiketech.gpx | 734 + reference/hiketech.ref | 1530 ++ reference/igc1.gpx | 2 +- reference/igc1_gpx.out | 3 +- reference/igc2_gpx.out | 3 +- reference/kartex-out.kwf | 13 + reference/kartex.txt | 16 + reference/mxf.mxf | 18 +- reference/ov2-in.ref | 18 +- reference/route/bcr-sample.gpx | 2 +- reference/route/compegps-rte.gpx | 48 + reference/route/compegps.rte | 20 + reference/route/cst-sample.cst | 351 + reference/route/cst-sample.cst.gz | Bin 0 -> 4470 bytes reference/route/cst-sample.gpx | 1312 ++ reference/route/mag_pdb-sample.gpx | 1034 ++ reference/route/mag_pdb-sample.pdb | Bin 0 -> 16183 bytes reference/route/magexplorist.rte | 6 + reference/route/msroute-sample.axe | Bin 0 -> 9216 bytes reference/route/msroute-sample.gpx | 90 + reference/route/nmn4-sample-out.rte | 10 + reference/route/nmn4-sample.gpx | 62 + reference/route/nmn4-sample.rte | 10 + reference/route/stmsdf-route.sdf | 18 + reference/route/stmwpp-route.gpx | 64 + reference/route/stmwpp-route.txt | 10 + reference/route/tef_xml.sample.gpx | 340 +- reference/sample.gtm | Bin 0 -> 90544 bytes reference/stmsdf.txt | 83 + reference/tpo-sample.tpo | Bin 0 -> 9293 bytes reference/tpo-sample3.gpx | 500 + reference/tpo-sample3.tpo | Bin 0 -> 7442 bytes reference/track/axim-sample.gpb | Bin 0 -> 4128 bytes reference/track/axim-sample.gpx | 62 + reference/track/compegps-trk.gpx | 183 + reference/track/compegps.trk | 53 + reference/track/dmtlog-sample.gpx | 669 + reference/track/fugawi.txt | 128 +- reference/track/i65.anr.gpx | 3312 ++-- reference/track/ignrando-sample.gpx | 45 + reference/track/ignrando-sample.rdn | 76 + reference/track/interptrack.gpx | 154 + reference/track/kartex-out.ktf | 179 + reference/track/kartex.txt | 182 + reference/track/nmea.gpx | 1708 ++ reference/track/pathaway.gpx | 995 +- reference/track/pcx.trk | 73 + reference/track/simpletrack.gpx | 21 + reference/track/sportsim-sample.txt | 66 + reference/track/stmsdf-track.sdf | 99 + reference/track/stmwpp-track.gpx | 173 + reference/track/stmwpp-track.txt | 54 + reference/track/tinterptrack.gpx | 58 + reference/track/tpo-sample1.gpx | 4839 +++++ reference/track/tpo-sample1.tpo | Bin 0 -> 9293 bytes reference/track/tpo-sample2.gpx | 3827 ++++ reference/track/tpo-sample2.tpo | Bin 0 -> 5933 bytes reference/track/trackDMm.ktf | 179 + reference/track/trackDd.ktf | 179 + reference/track/trackfilter-sdistance.gpx | 366 + reference/track/trackfilter-sdistance2.gpx | 281 + reference/track/trackfilter.gpx | 274 +- reference/track/tracks.gpssim | 128 + reference/track/tracks.gpx | 1 + reference/track/vitosmt_t.gpx | 3 +- reference/transform-rte.gpx | 783 + reference/transform-wpt.gpx | 378 + reference/unicsv.gpx | 55 + reference/vitosmt.gpx | 2 +- reference/waypoints.gpssim | 9 + reference/waypointsDMm.kwf | 13 + reference/waypointsDd.kwf | 13 + reference/wbt-200.bin | Bin 0 -> 3120 bytes reference/wbt-200.gpx | 790 + reference/wfff.gpu | 1 + reference/wfff.xml | 17 + reverse_route.c | 7 +- rgbcolors.c | 248 + route.c | 474 +- saroute.c | 221 +- shape.c | 142 +- shapelib/Makefile.in | 0 shapelib/dbfopen.c | 17 +- shapelib/shpopen.c | 16 +- smplrout.c | 104 +- sort.c | 58 +- stackfilter.c | 79 +- stmsdf.c | 724 + stmwpp.c | 303 + strptime.c | 8 +- style/README.style | 492 - style/arc.style | 7 +- style/cambridge.style | 18 + style/cup.style | 46 + style/custom.style | 2 +- style/garmin301.style | 34 + style/garmin_poi.style | 34 + style/geonet.style | 49 + style/gpsdrivetrack.style | 8 +- style/ktf2.style | 35 + style/kwf2.style | 38 + style/mxf.style | 6 +- style/openoffice.style | 4 +- style/s_and_t.style | 2 +- style/sportsim.style | 32 + style/xmap2006.style | 37 + tef_xml.c | 16 +- testc | 1 + testo | 797 +- testw | 166 + text.c | 123 +- tiger.c | 125 +- tmpro.c | 35 +- tomtom.c | 11 +- tools/functions | 41 + tools/gcfg | 17 + tools/{mkcapabilities => mkcapabilities.in} | 13 +- tools/mkchangelog | 62 + tools/mkfilelist | 51 + tools/mkmoreclean | 15 + tools/mkrpm | 93 + tools/mkspec | 56 + tools/release-process | 10 + tpg.c | 58 +- tpo.README.patch | 51 + tpo.c | 1962 ++ tpo.testo.patch | 27 + trackfilter.c | 315 +- transform.c | 194 + unicsv.c | 227 + units.c | 94 + util.c | 907 +- util_crc.c | 15 + uuid.c | 2 +- uuid.h | 2 +- vcf.c | 17 +- vecs.c | 588 +- vitosmt.c | 29 +- vmem.c | 2 +- waypt.c | 107 +- wbt-200.c | 651 + wfff_xml.c | 295 + win32/GPSBabelGUI.exe | Bin 495104 -> 1002504 bytes win32/gpsbabel.ico | Bin 0 -> 766 bytes win32/gpsbabel.rc.in | 27 + win32/gui-2/GPSBabelGUI.cfg | 35 + win32/gui-2/GPSBabelGUI.dof | 84 + win32/gui-2/GPSBabelGUI.dpr | 54 + win32/gui-2/GPSBabelGUI.ico | Bin 0 -> 766 bytes win32/gui-2/GPSBabelGUI.res | Bin 0 -> 1748 bytes win32/gui-2/Makefile | 60 + win32/gui-2/README.gui | 70 + win32/gui-2/about.dfm | Bin 0 -> 3505 bytes win32/gui-2/about.pas | 136 + win32/gui-2/common.pas | 562 + win32/gui-2/default.po | 833 + win32/gui-2/delphi.pas | 93 + win32/gui-2/dof2rc.dpr | 108 + win32/gui-2/filter.dfm | Bin 0 -> 8761 bytes win32/gui-2/filter.pas | 733 + win32/gui-2/gnugettext.pas | 2842 +++ win32/gui-2/gnugettextD4.pas | 290 + win32/gui-2/gnugettextD5.pas | 265 + win32/gui-2/gnugettextDx.pas | 72 + win32/gui-2/gpsbabel.iss | 120 + win32/gui-2/gpsbabel.po | 387 + win32/gui-2/ignore.po | 297 + win32/gui-2/locale/de/LC_MESSAGES/default.po | 903 + win32/gui-2/locale/de/LC_MESSAGES/delphi.po | 10164 +++++++++++ win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po | 398 + win32/gui-2/locale/fr/LC_MESSAGES/default.po | 904 + win32/gui-2/locale/fr/LC_MESSAGES/delphi.po | 6177 +++++++ win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po | 397 + win32/gui-2/main.dfm | Bin 0 -> 37152 bytes win32/gui-2/main.pas | 1362 ++ win32/gui-2/options.dfm | Bin 0 -> 1313 bytes win32/gui-2/options.pas | 820 + win32/gui-2/readme.dfm | Bin 0 -> 687 bytes win32/gui-2/readme.pas | 74 + win32/gui-2/select.dfm | Bin 0 -> 1450 bytes win32/gui-2/select.pas | 144 + win32/gui-2/utils.pas | 442 + xcsv.c | 89 +- xmldoc/babelmain.xsl | 35 + xmldoc/chapters/_chapters.xml | 10 + xmldoc/chapters/allchapters.xml | 8 + xmldoc/chapters/build.xml | 58 + xmldoc/chapters/datums.xml | 138 + xmldoc/chapters/filters.xml | 23 + xmldoc/chapters/formats.xml | 4 + xmldoc/chapters/garmin_icons.xml | 283 + xmldoc/chapters/preface.xml | 25 + xmldoc/chapters/styles.xml | 1104 ++ xmldoc/chapters/use.xml | 265 + xmldoc/filters/arc.xml | 42 + xmldoc/filters/discard.xml | 12 + xmldoc/filters/duplicate.xml | 20 + xmldoc/filters/interpolate.xml | 30 + xmldoc/filters/nuketypes.xml | 16 + xmldoc/filters/options/arc-distance.xml | 14 + xmldoc/filters/options/arc-exclude.xml | 6 + xmldoc/filters/options/arc-file.xml | 13 + xmldoc/filters/options/arc-points.xml | 11 + xmldoc/filters/options/discard-hdop.xml | 7 + .../filters/options/discard-hdopandvdop.xml | 6 + xmldoc/filters/options/discard-vdop.xml | 7 + xmldoc/filters/options/duplicate-all.xml | 17 + xmldoc/filters/options/duplicate-correct.xml | 21 + xmldoc/filters/options/duplicate-location.xml | 9 + .../filters/options/duplicate-shortname.xml | 9 + .../filters/options/interpolate-distance.xml | 13 + xmldoc/filters/options/interpolate-route.xml | 5 + xmldoc/filters/options/interpolate-time.xml | 12 + xmldoc/filters/options/nuketypes-routes.xml | 4 + xmldoc/filters/options/nuketypes-tracks.xml | 4 + .../filters/options/nuketypes-waypoints.xml | 5 + xmldoc/filters/options/polygon-exclude.xml | 6 + xmldoc/filters/options/polygon-file.xml | 16 + xmldoc/filters/options/position-all.xml | 8 + xmldoc/filters/options/position-distance.xml | 9 + xmldoc/filters/options/radius-asroute.xml | 13 + xmldoc/filters/options/radius-distance.xml | 13 + xmldoc/filters/options/radius-exclude.xml | 5 + xmldoc/filters/options/radius-lat.xml | 8 + xmldoc/filters/options/radius-lon.xml | 8 + xmldoc/filters/options/radius-maxcount.xml | 22 + xmldoc/filters/options/radius-nosort.xml | 6 + xmldoc/filters/options/simplify-count.xml | 8 + .../filters/options/simplify-crosstrack.xml | 11 + xmldoc/filters/options/simplify-error.xml | 13 + xmldoc/filters/options/simplify-length.xml | 4 + xmldoc/filters/options/sort-description.xml | 8 + xmldoc/filters/options/sort-gcid.xml | 8 + xmldoc/filters/options/sort-shortname.xml | 8 + xmldoc/filters/options/sort-time.xml | 8 + xmldoc/filters/options/stack-append.xml | 5 + xmldoc/filters/options/stack-copy.xml | 6 + xmldoc/filters/options/stack-depth.xml | 6 + xmldoc/filters/options/stack-discard.xml | 5 + xmldoc/filters/options/stack-pop.xml | 9 + xmldoc/filters/options/stack-push.xml | 8 + xmldoc/filters/options/stack-replace.xml | 8 + xmldoc/filters/options/stack-swap.xml | 10 + xmldoc/filters/options/track-course.xml | 10 + xmldoc/filters/options/track-fix.xml | 9 + xmldoc/filters/options/track-merge.xml | 14 + xmldoc/filters/options/track-move.xml | 13 + xmldoc/filters/options/track-name.xml | 7 + xmldoc/filters/options/track-pack.xml | 12 + xmldoc/filters/options/track-sdistance.xml | 36 + xmldoc/filters/options/track-speed.xml | 9 + xmldoc/filters/options/track-split.xml | 32 + xmldoc/filters/options/track-start.xml | 24 + xmldoc/filters/options/track-stop.xml | 15 + xmldoc/filters/options/track-title.xml | 10 + xmldoc/filters/polygon.xml | 78 + xmldoc/filters/position.xml | 15 + xmldoc/filters/radius.xml | 17 + xmldoc/filters/reverse.xml | 19 + xmldoc/filters/simplify.xml | 21 + xmldoc/filters/sort.xml | 5 + xmldoc/filters/stack.xml | 49 + xmldoc/filters/track.xml | 8 + xmldoc/filters/transform.xml | 16 + xmldoc/formats/an1.xml | 15 + xmldoc/formats/arc.xml | 6 + xmldoc/formats/axim_gpb.xml | 10 + xmldoc/formats/baroiq.xml | 5 + xmldoc/formats/bcr.xml | 21 + xmldoc/formats/cambridge.xml | 6 + xmldoc/formats/cetus.xml | 7 + xmldoc/formats/coastexp.xml | 8 + xmldoc/formats/compegps.xml | 14 + xmldoc/formats/copilot.xml | 14 + xmldoc/formats/coto.xml | 20 + xmldoc/formats/cst.xml | 9 + xmldoc/formats/csv.xml | 12 + xmldoc/formats/cup.xml | 14 + xmldoc/formats/custom.xml | 9 + xmldoc/formats/dmtlog.xml | 10 + xmldoc/formats/dna.xml | 8 + xmldoc/formats/easygps.xml | 15 + xmldoc/formats/fugawi.xml | 27 + xmldoc/formats/garmin.xml | 166 + xmldoc/formats/garmin301.xml | 8 + xmldoc/formats/garmin_poi.xml | 9 + xmldoc/formats/garmin_txt.xml | 23 + xmldoc/formats/gcdb.xml | 7 + xmldoc/formats/gdb.xml | 11 + xmldoc/formats/geo.xml | 11 + xmldoc/formats/geonet.xml | 8 + xmldoc/formats/geoniche.xml | 8 + xmldoc/formats/glogbook.xml | 7 + xmldoc/formats/google.xml | 36 + xmldoc/formats/gpilots.xml | 12 + xmldoc/formats/gpl.xml | 8 + xmldoc/formats/gpsdrive.xml | 7 + xmldoc/formats/gpsdrivetrack.xml | 7 + xmldoc/formats/gpsman.xml | 13 + xmldoc/formats/gpspilot.xml | 10 + xmldoc/formats/gpssim.xml | 9 + xmldoc/formats/gpsutil.xml | 8 + xmldoc/formats/gpx.xml | 9 + xmldoc/formats/gtm.xml | 5 + xmldoc/formats/gtrnctr.xml | 17 + xmldoc/formats/hiketech.xml | 8 + xmldoc/formats/holux.xml | 28 + xmldoc/formats/hsandv.xml | 8 + xmldoc/formats/html.xml | 11 + xmldoc/formats/igc.xml | 134 + xmldoc/formats/ignrando.xml | 6 + xmldoc/formats/kml.xml | 10 + xmldoc/formats/ktf2.xml | 5 + xmldoc/formats/kwf2.xml | 9 + xmldoc/formats/lowranceusr.xml | 9 + xmldoc/formats/mag_pdb.xml | 10 + xmldoc/formats/magellan.xml | 37 + xmldoc/formats/magellan1.xml | 40 + xmldoc/formats/magellanx.xml | 14 + xmldoc/formats/maggeo.xml | 11 + xmldoc/formats/magnav.xml | 44 + xmldoc/formats/mapconverter.xml | 61 + xmldoc/formats/mapsend.xml | 8 + xmldoc/formats/mapsource.xml | 28 + xmldoc/formats/msroute.xml | 20 + xmldoc/formats/msroute1.xml | 20 + xmldoc/formats/mxf.xml | 8 + xmldoc/formats/navicache.xml | 9 + xmldoc/formats/netstumbler.xml | 21 + xmldoc/formats/nima.xml | 6 + xmldoc/formats/nmea.xml | 36 + xmldoc/formats/nmn4.xml | 10 + xmldoc/formats/openoffice.xml | 11 + xmldoc/formats/options/an1-color.xml | 4 + xmldoc/formats/options/an1-deficon.xml | 7 + xmldoc/formats/options/an1-nogc.xml | 8 + xmldoc/formats/options/an1-radius.xml | 5 + xmldoc/formats/options/an1-road.xml | 79 + xmldoc/formats/options/an1-type.xml | 7 + xmldoc/formats/options/an1-wpt_type.xml | 13 + xmldoc/formats/options/an1-zoom.xml | 7 + xmldoc/formats/options/bcr-index.xml | 9 + xmldoc/formats/options/bcr-name.xml | 5 + xmldoc/formats/options/bcr-radius.xml | 9 + xmldoc/formats/options/cetus-appendicon.xml | 7 + xmldoc/formats/options/cetus-dbname.xml | 6 + xmldoc/formats/options/compegps-deficon.xml | 3 + xmldoc/formats/options/compegps-index.xml | 8 + xmldoc/formats/options/compegps-radius.xml | 3 + xmldoc/formats/options/compegps-snlen.xml | 4 + xmldoc/formats/options/coto-zerocat.xml | 4 + xmldoc/formats/options/dmtlog-index.xml | 16 + xmldoc/formats/options/garmin-category.xml | 3 + xmldoc/formats/options/garmin-deficon.xml | 17 + xmldoc/formats/options/garmin-get_posn.xml | 5 + xmldoc/formats/options/garmin-power_off.xml | 8 + xmldoc/formats/options/garmin-snlen.xml | 7 + xmldoc/formats/options/garmin-snwhite.xml | 2 + xmldoc/formats/options/garmin_txt-date.xml | 4 + xmldoc/formats/options/garmin_txt-datum.xml | 4 + xmldoc/formats/options/garmin_txt-dist.xml | 5 + xmldoc/formats/options/garmin_txt-prec.xml | 5 + xmldoc/formats/options/garmin_txt-temp.xml | 4 + xmldoc/formats/options/garmin_txt-time.xml | 4 + xmldoc/formats/options/garmin_txt-utc.xml | 5 + xmldoc/formats/options/gdb-cat.xml | 4 + xmldoc/formats/options/gdb-ver.xml | 5 + xmldoc/formats/options/gdb-via.xml | 5 + xmldoc/formats/options/geo-deficon.xml | 17 + xmldoc/formats/options/geo-nuke_placer.xml | 9 + xmldoc/formats/options/geoniche-category.xml | 6 + xmldoc/formats/options/geoniche-dbname.xml | 6 + xmldoc/formats/options/gpilots-dbname.xml | 6 + xmldoc/formats/options/gpspilot-dbname.xml | 6 + xmldoc/formats/options/gpssim-split.xml | 17 + xmldoc/formats/options/gpssim-wayptspd.xml | 3 + xmldoc/formats/options/gpx-gpxver.xml | 11 + xmldoc/formats/options/gpx-logpoint.xml | 1 + xmldoc/formats/options/gpx-snlen.xml | 1 + xmldoc/formats/options/gpx-suppresswhite.xml | 1 + xmldoc/formats/options/gpx-urlbase.xml | 1 + xmldoc/formats/options/html-altunits.xml | 4 + xmldoc/formats/options/html-degformat.xml | 5 + xmldoc/formats/options/html-encrypt.xml | 3 + xmldoc/formats/options/html-logs.xml | 3 + xmldoc/formats/options/html-stylesheet.xml | 4 + xmldoc/formats/options/igc-timeadj.xml | 16 + xmldoc/formats/options/ignrando-index.xml | 9 + xmldoc/formats/options/kml-deficon.xml | 3 + xmldoc/formats/options/kml-extrude.xml | 7 + xmldoc/formats/options/kml-floating.xml | 9 + xmldoc/formats/options/kml-labels.xml | 4 + xmldoc/formats/options/kml-line_color.xml | 5 + xmldoc/formats/options/kml-line_width.xml | 4 + xmldoc/formats/options/kml-lines.xml | 6 + .../options/kml-max_position_points.xml | 4 + xmldoc/formats/options/kml-points.xml | 6 + xmldoc/formats/options/kml-trackdata.xml | 8 + xmldoc/formats/options/kml-units.xml | 5 + xmldoc/formats/options/lowranceusr-break.xml | 4 + .../options/lowranceusr-ignoreicons.xml | 3 + xmldoc/formats/options/lowranceusr-merge.xml | 3 + xmldoc/formats/options/magellan-deficon.xml | 1 + xmldoc/formats/options/magellan-maxcmts.xml | 13 + xmldoc/formats/options/magellan1-baud.xml | 8 + xmldoc/formats/options/magellan1-deficon.xml | 15 + xmldoc/formats/options/magellan1-maxcmts.xml | 13 + xmldoc/formats/options/magellan1-noack.xml | 17 + xmldoc/formats/options/magellan1-nukewpt.xml | 10 + xmldoc/formats/options/magellanx-deficon.xml | 1 + xmldoc/formats/options/magellanx-maxcmts.xml | 13 + xmldoc/formats/options/mapsend-trkver.xml | 6 + .../formats/options/mapsource-mpsmergeout.xml | 5 + .../formats/options/mapsource-mpsusedepth.xml | 5 + .../formats/options/mapsource-mpsuseprox.xml | 5 + .../formats/options/mapsource-mpsverout.xml | 5 + xmldoc/formats/options/mapsource-snlen.xml | 4 + xmldoc/formats/options/mapsource-snwhite.xml | 4 + .../formats/options/navicache-noretired.xml | 1 + .../formats/options/netstumbler-nseicon.xml | 4 + .../formats/options/netstumbler-nsneicon.xml | 4 + xmldoc/formats/options/netstumbler-seicon.xml | 4 + .../formats/options/netstumbler-sneicon.xml | 4 + xmldoc/formats/options/netstumbler-snmac.xml | 4 + xmldoc/formats/options/nmea-baud.xml | 4 + xmldoc/formats/options/nmea-date.xml | 10 + xmldoc/formats/options/nmea-get_posn.xml | 3 + xmldoc/formats/options/nmea-gpgga.xml | 8 + xmldoc/formats/options/nmea-gpgsa.xml | 12 + xmldoc/formats/options/nmea-gprmc.xml | 11 + xmldoc/formats/options/nmea-gpvtg.xml | 11 + xmldoc/formats/options/nmea-pause.xml | 31 + xmldoc/formats/options/nmea-snlen.xml | 6 + xmldoc/formats/options/nmn4-index.xml | 9 + xmldoc/formats/options/ozi-snlen.xml | 1 + xmldoc/formats/options/ozi-snunique.xml | 1 + xmldoc/formats/options/ozi-snupper.xml | 1 + xmldoc/formats/options/ozi-snwhite.xml | 1 + xmldoc/formats/options/ozi-wptbgcolor.xml | 1 + xmldoc/formats/options/ozi-wptfgcolor.xml | 1 + .../options/palmdoc-bookmarks_short.xml | 9 + xmldoc/formats/options/palmdoc-dbname.xml | 5 + xmldoc/formats/options/palmdoc-encrypt.xml | 3 + xmldoc/formats/options/palmdoc-logs.xml | 3 + xmldoc/formats/options/palmdoc-nosep.xml | 3 + xmldoc/formats/options/pathaway-date.xml | 4 + xmldoc/formats/options/pathaway-dbname.xml | 6 + xmldoc/formats/options/pathaway-deficon.xml | 1 + xmldoc/formats/options/pathaway-snlen.xml | 1 + xmldoc/formats/options/pcx-cartoexploreur.xml | 1 + xmldoc/formats/options/pcx-deficon.xml | 1 + xmldoc/formats/options/quovadis-dbname.xml | 6 + xmldoc/formats/options/saroute-controls.xml | 10 + xmldoc/formats/options/saroute-split.xml | 5 + xmldoc/formats/options/saroute-times.xml | 5 + .../options/saroute-turns_important.xml | 6 + xmldoc/formats/options/saroute-turns_only.xml | 4 + xmldoc/formats/options/stmsdf-index.xml | 17 + xmldoc/formats/options/stmwpp-index.xml | 9 + xmldoc/formats/options/tef-routevia.xml | 3 + xmldoc/formats/options/text-altunits.xml | 4 + xmldoc/formats/options/text-degformat.xml | 5 + xmldoc/formats/options/text-encrypt.xml | 3 + xmldoc/formats/options/text-logs.xml | 3 + xmldoc/formats/options/text-nosep.xml | 3 + xmldoc/formats/options/tiger-genurl.xml | 18 + xmldoc/formats/options/tiger-iconismarker.xml | 4 + xmldoc/formats/options/tiger-margin.xml | 7 + xmldoc/formats/options/tiger-newmarker.xml | 3 + xmldoc/formats/options/tiger-nolabels.xml | 3 + xmldoc/formats/options/tiger-oldmarker.xml | 3 + xmldoc/formats/options/tiger-oldthresh.xml | 5 + xmldoc/formats/options/tiger-snlen.xml | 5 + .../formats/options/tiger-suppresswhite.xml | 4 + .../formats/options/tiger-unfoundmarker.xml | 1 + xmldoc/formats/options/tiger-xpixels.xml | 3 + xmldoc/formats/options/tiger-ypixels.xml | 4 + xmldoc/formats/options/tpg-datum.xml | 5 + xmldoc/formats/options/vcard-encrypt.xml | 4 + xmldoc/formats/options/wbt-erase.xml | 1 + xmldoc/formats/options/wfff-ahcicon.xml | 1 + xmldoc/formats/options/wfff-ahoicon.xml | 1 + xmldoc/formats/options/wfff-aicicon.xml | 1 + xmldoc/formats/options/wfff-aioicon.xml | 1 + xmldoc/formats/options/wfff-snmac.xml | 1 + .../options/xcsv-prefer_shortnames.xml | 7 + xmldoc/formats/options/xcsv-snlen.xml | 8 + xmldoc/formats/options/xcsv-snunique.xml | 8 + xmldoc/formats/options/xcsv-snupper.xml | 8 + xmldoc/formats/options/xcsv-snwhite.xml | 7 + xmldoc/formats/options/xcsv-style.xml | 10 + xmldoc/formats/options/xcsv-urlbase.xml | 5 + xmldoc/formats/options/yahoo-addrsep.xml | 9 + xmldoc/formats/ozi.xml | 7 + xmldoc/formats/palmdoc.xml | 13 + xmldoc/formats/pathaway.xml | 10 + xmldoc/formats/pcx.xml | 13 + xmldoc/formats/psitrex.xml | 10 + xmldoc/formats/psp.xml | 223 + xmldoc/formats/quovadis.xml | 21 + xmldoc/formats/s_and_t.xml | 9 + xmldoc/formats/saplus.xml | 17 + xmldoc/formats/saroute.xml | 9 + xmldoc/formats/sportsim.xml | 14 + xmldoc/formats/stmsdf.xml | 23 + xmldoc/formats/stmwpp.xml | 10 + xmldoc/formats/tabsep.xml | 12 + xmldoc/formats/tef.xml | 15 + xmldoc/formats/text.xml | 8 + xmldoc/formats/tiger.xml | 9 + xmldoc/formats/tmpro.xml | 10 + xmldoc/formats/tomtom.xml | 15 + xmldoc/formats/tpg.xml | 8 + xmldoc/formats/tpo.xml | 12 + xmldoc/formats/tpo2.xml | 9 + xmldoc/formats/tpo3.xml | 6 + xmldoc/formats/unicsv.xml | 26 + xmldoc/formats/vcard.xml | 13 + xmldoc/formats/vitosmt.xml | 10 + xmldoc/formats/wbt-bin.xml | 12 + xmldoc/formats/wbt.xml | 9 + xmldoc/formats/wfff.xml | 7 + xmldoc/formats/xcsv.xml | 14 + xmldoc/formats/xmap.xml | 9 + xmldoc/formats/xmap2006.xml | 10 + xmldoc/formats/xmapwpt.xml | 77 + xmldoc/formats/yahoo.xml | 7 + xmldoc/gpsbabel_man.xml | 81 + xmldoc/makedoc.in | 217 + xmldoc/old/extract | 4 + xmldoc/old/extract.xsl | 11 + xmldoc/old/readme.xml | 2296 +++ xmldoc/readme.xml | 20 + xmlgeneric.c | 108 +- xmlgeneric.h | 1 + xmltag.c | 27 +- yahoo.c | 119 + zlib/ChangeLog | 860 + zlib/FAQ | 339 + zlib/Makefile.in.zlib | 154 + zlib/README | 125 + zlib/README.gpsbabel | 3 + zlib/adler32.c | 149 + zlib/algorithm.txt | 209 + zlib/compress.c | 79 + zlib/crc32.c | 423 + zlib/crc32.h | 441 + zlib/deflate.c | 1736 ++ zlib/deflate.h | 331 + zlib/empty.in | 0 zlib/gzio.c | 1026 ++ zlib/infback.c | 623 + zlib/inffast.c | 318 + zlib/inffast.h | 11 + zlib/inffixed.h | 94 + zlib/inflate.c | 1368 ++ zlib/inflate.h | 115 + zlib/inftrees.c | 329 + zlib/inftrees.h | 55 + zlib/trees.c | 1219 ++ zlib/trees.h | 128 + zlib/uncompr.c | 61 + zlib/zconf.h | 332 + zlib/zconf.in.h | 332 + zlib/zlib.3 | 159 + zlib/zlib.h | 1357 ++ zlib/zutil.c | 318 + zlib/zutil.h | 269 + 902 files changed, 154383 insertions(+), 26831 deletions(-) create mode 100644 AUTHORS delete mode 100644 ChangeLog delete mode 100644 Makefile create mode 100644 Makefile.in delete mode 100644 README create mode 100644 axim_gpb.c create mode 100644 cet.c create mode 100644 cet.h create mode 100644 cet/ansi_x3_4_1968.h create mode 100644 cet/atarist.h create mode 100644 cet/baltic.h create mode 100644 cet/bs_4730.h create mode 100644 cet/bs_viewdata.h create mode 100644 cet/cp1250.h create mode 100644 cet/cp1251.h create mode 100644 cet/cp1252.h create mode 100644 cet/cp1253.h create mode 100644 cet/cp1254.h create mode 100644 cet/cp1255.h create mode 100644 cet/cp1256.h create mode 100644 cet/cp1257.h create mode 100644 cet/csa_z243_4_1985_1.h create mode 100644 cet/csa_z243_4_1985_2.h create mode 100644 cet/csa_z243_4_1985_gr.h create mode 100644 cet/csn_369103.h create mode 100644 cet/cwi.h create mode 100644 cet/dec_mcs.h create mode 100644 cet/din_66003.h create mode 100644 cet/ds_2089.h create mode 100644 cet/ecma_cyrillic.h create mode 100644 cet/es.h create mode 100644 cet/es2.h create mode 100644 cet/gb_1988_80.h create mode 100644 cet/gost_19768_87.h create mode 100644 cet/hp_roman8.h create mode 100644 cet/ibm037.h create mode 100644 cet/ibm1004.h create mode 100644 cet/ibm1026.h create mode 100644 cet/ibm1047.h create mode 100644 cet/ibm256.h create mode 100644 cet/ibm273.h create mode 100644 cet/ibm277.h create mode 100644 cet/ibm278.h create mode 100644 cet/ibm280.h create mode 100644 cet/ibm284.h create mode 100644 cet/ibm285.h create mode 100644 cet/ibm297.h create mode 100644 cet/ibm437.h create mode 100644 cet/ibm500.h create mode 100644 cet/ibm850.h create mode 100644 cet/ibm851.h create mode 100644 cet/ibm852.h create mode 100644 cet/ibm855.h create mode 100644 cet/ibm857.h create mode 100644 cet/ibm860.h create mode 100644 cet/ibm861.h create mode 100644 cet/ibm862.h create mode 100644 cet/ibm863.h create mode 100644 cet/ibm864.h create mode 100644 cet/ibm865.h create mode 100644 cet/ibm868.h create mode 100644 cet/ibm869.h create mode 100644 cet/ibm871.h create mode 100644 cet/ibm891.h create mode 100644 cet/ibm903.h create mode 100644 cet/ibm904.h create mode 100644 cet/iec_p27_1.h create mode 100644 cet/iso_10367_box.h create mode 100644 cet/iso_5427.h create mode 100644 cet/iso_646_irv.h create mode 100644 cet/iso_6937_2_25.h create mode 100644 cet/iso_8859_1.h create mode 100644 cet/iso_8859_10.h create mode 100644 cet/iso_8859_13.h create mode 100644 cet/iso_8859_14.h create mode 100644 cet/iso_8859_15.h create mode 100644 cet/iso_8859_2.h create mode 100644 cet/iso_8859_3.h create mode 100644 cet/iso_8859_4.h create mode 100644 cet/iso_8859_5.h create mode 100644 cet/iso_8859_6.h create mode 100644 cet/iso_8859_7.h create mode 100644 cet/iso_8859_8.h create mode 100644 cet/iso_8859_9.h create mode 100644 cet/iso_8859_supp.h create mode 100644 cet/it.h create mode 100644 cet/jis_c6220_1969_ro.h create mode 100644 cet/jis_x0201.h create mode 100644 cet/jus_i_b1_002.h create mode 100644 cet/jus_i_b1_003_mac.h create mode 100644 cet/jus_i_b1_003_serb.h create mode 100644 cet/keybcs2.h create mode 100644 cet/koi8_r.h create mode 100644 cet/koi8_ru.h create mode 100644 cet/koi8_u.h create mode 100644 cet/koi_7.h create mode 100644 cet/koi_8.h create mode 100644 cet/koi_8_cs2.h create mode 100644 cet/ksc5636.h create mode 100644 cet/latin_greek_1.h create mode 100644 cet/mac_is.h create mode 100644 cet/macintosh.h create mode 100644 cet/macintosh_ce.h create mode 100644 cet/msz_7795_3.h create mode 100644 cet/nats_dano.h create mode 100644 cet/nats_sefi.h create mode 100644 cet/nc_nc00_10.h create mode 100644 cet/nextstep.h create mode 100644 cet/nf_z_62_010.h create mode 100644 cet/nf_z_62_010__1973_.h create mode 100644 cet/ns_4551_1.h create mode 100644 cet/ns_4551_2.h create mode 100644 cet/pt.h create mode 100644 cet/pt2.h create mode 100644 cet/sami.h create mode 100644 cet/sen_850200_b.h create mode 100644 cet/sen_850200_c.h create mode 100644 cet/tcvn.h create mode 100644 cet/viscii.h create mode 100644 cet/vps.h create mode 100644 cet_util.c create mode 100644 cet_util.h create mode 100644 coldsync/Makefile.in rename coldsync/{config.h => cs-config.h} (100%) create mode 100644 compegps.c create mode 100644 config.guess create mode 100644 config.h.in create mode 100644 config.sub create mode 100644 configure create mode 100644 configure.in create mode 100644 cst.c create mode 100644 dmtlog.c create mode 100644 fatal.c create mode 100644 filterdefs.h create mode 100644 format_skeleton.c create mode 100644 garmin_fs.c create mode 100644 garmin_fs.h create mode 100644 garmin_txt.c create mode 100644 gbfile.c create mode 100644 gbfile.h create mode 100644 gbser.c create mode 100644 gbser.h create mode 100644 gbser_posix.c create mode 100644 gbser_private.h create mode 100644 gbser_win.c create mode 100644 gbsleep.c create mode 100644 globals.c create mode 100644 gpsbabel-sample.ini create mode 100644 gpsbabel.html create mode 100644 gpssim.c create mode 100644 gtm.c create mode 100644 gtrnctr.c create mode 100644 ignrando.c create mode 100644 inifile.c create mode 100644 inifile.h create mode 100644 install-sh create mode 100644 intdoc/an1_road_types.txt create mode 100644 intdoc/jeeps-device.odg create mode 100644 interpolate.c create mode 100644 jeeps/Makefile.in create mode 100644 jeeps/gpsdevice.c create mode 100644 jeeps/gpsdevice.h create mode 100644 jeeps/gpsdevice_ser.c create mode 100644 jeeps/gpsdevice_usb.c delete mode 100644 jeeps/gpsnmea.h delete mode 100644 jeeps/gpsnmeafmt.h delete mode 100644 jeeps/gpsnmeaget.h create mode 100644 jeeps/gpsusbcommon.c create mode 100644 jeeps/gpsusbcommon.h create mode 100644 macgpsbabel/Info.plist create mode 100644 macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj create mode 100644 mag_pdb.c create mode 100644 mingw/libw/README create mode 100644 mingw/libw/libexpat.a create mode 100644 mkicondoc.c create mode 100644 msroute.c create mode 100644 msvc/Debug.empty create mode 100644 msvc/Expatw/expat.h create mode 100644 msvc/Expatw/expat_external.h create mode 100644 msvc/Expatw/libexpatw.dll create mode 100644 msvc/Expatw/libexpatw.lib create mode 100644 msvc/Unicode.empty create mode 100644 msvc/build.bat create mode 100644 msvc/config.h create mode 100644 msvc/release.empty create mode 100644 nmn4.c create mode 100644 nukedata.c create mode 100644 radius.c create mode 100644 reference/cet/cet-sample.cp1250.txt create mode 100644 reference/cet/cet-sample.gdb create mode 100644 reference/cet/cet-sample.gpx create mode 100644 reference/cet/cet-sample.latin1.txt create mode 100644 reference/cet/cet-sample.latin2.txt create mode 100644 reference/cet/cet-sample.macroman.txt create mode 100644 reference/compegps-wpt.gpx create mode 100644 reference/compegps.wpt create mode 100644 reference/compegps.wpt.gz create mode 100644 reference/earth-expertgps.kml create mode 100644 reference/earth-gc.kml create mode 100644 reference/garmin_txt.txt create mode 100644 reference/gc/maggeo.gs create mode 100644 reference/gdb-sample2.gdb create mode 100644 reference/geonet-sample.gpx create mode 100644 reference/geonet-sample.txt create mode 100644 reference/gn-targets.gpx create mode 100644 reference/gn-targets.pdb create mode 100644 reference/google.csv create mode 100644 reference/google_jan_06.csv create mode 100644 reference/google_jan_06.html create mode 100644 reference/hiketech.gpx create mode 100644 reference/hiketech.ref create mode 100644 reference/kartex-out.kwf create mode 100644 reference/kartex.txt create mode 100644 reference/route/compegps-rte.gpx create mode 100644 reference/route/compegps.rte create mode 100644 reference/route/cst-sample.cst create mode 100644 reference/route/cst-sample.cst.gz create mode 100644 reference/route/cst-sample.gpx create mode 100644 reference/route/mag_pdb-sample.gpx create mode 100644 reference/route/mag_pdb-sample.pdb create mode 100644 reference/route/magexplorist.rte create mode 100644 reference/route/msroute-sample.axe create mode 100644 reference/route/msroute-sample.gpx create mode 100644 reference/route/nmn4-sample-out.rte create mode 100644 reference/route/nmn4-sample.gpx create mode 100644 reference/route/nmn4-sample.rte create mode 100644 reference/route/stmsdf-route.sdf create mode 100644 reference/route/stmwpp-route.gpx create mode 100644 reference/route/stmwpp-route.txt create mode 100644 reference/sample.gtm create mode 100644 reference/stmsdf.txt create mode 100644 reference/tpo-sample.tpo create mode 100644 reference/tpo-sample3.gpx create mode 100644 reference/tpo-sample3.tpo create mode 100644 reference/track/axim-sample.gpb create mode 100644 reference/track/axim-sample.gpx create mode 100644 reference/track/compegps-trk.gpx create mode 100644 reference/track/compegps.trk create mode 100644 reference/track/dmtlog-sample.gpx create mode 100644 reference/track/ignrando-sample.gpx create mode 100644 reference/track/ignrando-sample.rdn create mode 100644 reference/track/interptrack.gpx create mode 100644 reference/track/kartex-out.ktf create mode 100644 reference/track/kartex.txt create mode 100644 reference/track/nmea.gpx create mode 100644 reference/track/pcx.trk create mode 100644 reference/track/simpletrack.gpx create mode 100644 reference/track/sportsim-sample.txt create mode 100644 reference/track/stmsdf-track.sdf create mode 100644 reference/track/stmwpp-track.gpx create mode 100644 reference/track/stmwpp-track.txt create mode 100644 reference/track/tinterptrack.gpx create mode 100644 reference/track/tpo-sample1.gpx create mode 100644 reference/track/tpo-sample1.tpo create mode 100644 reference/track/tpo-sample2.gpx create mode 100644 reference/track/tpo-sample2.tpo create mode 100644 reference/track/trackDMm.ktf create mode 100644 reference/track/trackDd.ktf create mode 100644 reference/track/trackfilter-sdistance.gpx create mode 100644 reference/track/trackfilter-sdistance2.gpx create mode 100644 reference/track/tracks.gpssim create mode 100644 reference/transform-rte.gpx create mode 100644 reference/transform-wpt.gpx create mode 100644 reference/unicsv.gpx create mode 100644 reference/waypoints.gpssim create mode 100644 reference/waypointsDMm.kwf create mode 100644 reference/waypointsDd.kwf create mode 100644 reference/wbt-200.bin create mode 100644 reference/wbt-200.gpx create mode 100644 reference/wfff.gpu create mode 100644 reference/wfff.xml create mode 100644 rgbcolors.c create mode 100644 shapelib/Makefile.in create mode 100644 stmsdf.c create mode 100644 stmwpp.c delete mode 100644 style/README.style create mode 100644 style/cambridge.style create mode 100644 style/cup.style create mode 100644 style/garmin301.style create mode 100644 style/garmin_poi.style create mode 100644 style/geonet.style create mode 100644 style/ktf2.style create mode 100644 style/kwf2.style create mode 100644 style/sportsim.style create mode 100644 style/xmap2006.style create mode 100644 testw create mode 100644 tools/functions create mode 100644 tools/gcfg rename tools/{mkcapabilities => mkcapabilities.in} (64%) create mode 100644 tools/mkchangelog create mode 100644 tools/mkfilelist create mode 100644 tools/mkmoreclean create mode 100644 tools/mkrpm create mode 100644 tools/mkspec create mode 100644 tools/release-process create mode 100644 tpo.README.patch create mode 100644 tpo.c create mode 100644 tpo.testo.patch create mode 100644 transform.c create mode 100644 unicsv.c create mode 100644 units.c create mode 100644 wbt-200.c create mode 100644 wfff_xml.c create mode 100644 win32/gpsbabel.ico create mode 100644 win32/gpsbabel.rc.in create mode 100644 win32/gui-2/GPSBabelGUI.cfg create mode 100644 win32/gui-2/GPSBabelGUI.dof create mode 100644 win32/gui-2/GPSBabelGUI.dpr create mode 100644 win32/gui-2/GPSBabelGUI.ico create mode 100644 win32/gui-2/GPSBabelGUI.res create mode 100644 win32/gui-2/Makefile create mode 100644 win32/gui-2/README.gui create mode 100644 win32/gui-2/about.dfm create mode 100644 win32/gui-2/about.pas create mode 100644 win32/gui-2/common.pas create mode 100644 win32/gui-2/default.po create mode 100644 win32/gui-2/delphi.pas create mode 100644 win32/gui-2/dof2rc.dpr create mode 100644 win32/gui-2/filter.dfm create mode 100644 win32/gui-2/filter.pas create mode 100644 win32/gui-2/gnugettext.pas create mode 100644 win32/gui-2/gnugettextD4.pas create mode 100644 win32/gui-2/gnugettextD5.pas create mode 100644 win32/gui-2/gnugettextDx.pas create mode 100644 win32/gui-2/gpsbabel.iss create mode 100644 win32/gui-2/gpsbabel.po create mode 100644 win32/gui-2/ignore.po create mode 100644 win32/gui-2/locale/de/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/de/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po create mode 100644 win32/gui-2/locale/fr/LC_MESSAGES/default.po create mode 100644 win32/gui-2/locale/fr/LC_MESSAGES/delphi.po create mode 100644 win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po create mode 100644 win32/gui-2/main.dfm create mode 100644 win32/gui-2/main.pas create mode 100644 win32/gui-2/options.dfm create mode 100644 win32/gui-2/options.pas create mode 100644 win32/gui-2/readme.dfm create mode 100644 win32/gui-2/readme.pas create mode 100644 win32/gui-2/select.dfm create mode 100644 win32/gui-2/select.pas create mode 100644 win32/gui-2/utils.pas create mode 100644 xmldoc/babelmain.xsl create mode 100644 xmldoc/chapters/_chapters.xml create mode 100644 xmldoc/chapters/allchapters.xml create mode 100644 xmldoc/chapters/build.xml create mode 100644 xmldoc/chapters/datums.xml create mode 100644 xmldoc/chapters/filters.xml create mode 100644 xmldoc/chapters/formats.xml create mode 100644 xmldoc/chapters/garmin_icons.xml create mode 100644 xmldoc/chapters/preface.xml create mode 100644 xmldoc/chapters/styles.xml create mode 100644 xmldoc/chapters/use.xml create mode 100644 xmldoc/filters/arc.xml create mode 100644 xmldoc/filters/discard.xml create mode 100644 xmldoc/filters/duplicate.xml create mode 100644 xmldoc/filters/interpolate.xml create mode 100644 xmldoc/filters/nuketypes.xml create mode 100644 xmldoc/filters/options/arc-distance.xml create mode 100644 xmldoc/filters/options/arc-exclude.xml create mode 100644 xmldoc/filters/options/arc-file.xml create mode 100644 xmldoc/filters/options/arc-points.xml create mode 100644 xmldoc/filters/options/discard-hdop.xml create mode 100644 xmldoc/filters/options/discard-hdopandvdop.xml create mode 100644 xmldoc/filters/options/discard-vdop.xml create mode 100644 xmldoc/filters/options/duplicate-all.xml create mode 100644 xmldoc/filters/options/duplicate-correct.xml create mode 100644 xmldoc/filters/options/duplicate-location.xml create mode 100644 xmldoc/filters/options/duplicate-shortname.xml create mode 100644 xmldoc/filters/options/interpolate-distance.xml create mode 100644 xmldoc/filters/options/interpolate-route.xml create mode 100644 xmldoc/filters/options/interpolate-time.xml create mode 100644 xmldoc/filters/options/nuketypes-routes.xml create mode 100644 xmldoc/filters/options/nuketypes-tracks.xml create mode 100644 xmldoc/filters/options/nuketypes-waypoints.xml create mode 100644 xmldoc/filters/options/polygon-exclude.xml create mode 100644 xmldoc/filters/options/polygon-file.xml create mode 100644 xmldoc/filters/options/position-all.xml create mode 100644 xmldoc/filters/options/position-distance.xml create mode 100644 xmldoc/filters/options/radius-asroute.xml create mode 100644 xmldoc/filters/options/radius-distance.xml create mode 100644 xmldoc/filters/options/radius-exclude.xml create mode 100644 xmldoc/filters/options/radius-lat.xml create mode 100644 xmldoc/filters/options/radius-lon.xml create mode 100644 xmldoc/filters/options/radius-maxcount.xml create mode 100644 xmldoc/filters/options/radius-nosort.xml create mode 100644 xmldoc/filters/options/simplify-count.xml create mode 100644 xmldoc/filters/options/simplify-crosstrack.xml create mode 100644 xmldoc/filters/options/simplify-error.xml create mode 100644 xmldoc/filters/options/simplify-length.xml create mode 100644 xmldoc/filters/options/sort-description.xml create mode 100644 xmldoc/filters/options/sort-gcid.xml create mode 100644 xmldoc/filters/options/sort-shortname.xml create mode 100644 xmldoc/filters/options/sort-time.xml create mode 100644 xmldoc/filters/options/stack-append.xml create mode 100644 xmldoc/filters/options/stack-copy.xml create mode 100644 xmldoc/filters/options/stack-depth.xml create mode 100644 xmldoc/filters/options/stack-discard.xml create mode 100644 xmldoc/filters/options/stack-pop.xml create mode 100644 xmldoc/filters/options/stack-push.xml create mode 100644 xmldoc/filters/options/stack-replace.xml create mode 100644 xmldoc/filters/options/stack-swap.xml create mode 100644 xmldoc/filters/options/track-course.xml create mode 100644 xmldoc/filters/options/track-fix.xml create mode 100644 xmldoc/filters/options/track-merge.xml create mode 100644 xmldoc/filters/options/track-move.xml create mode 100644 xmldoc/filters/options/track-name.xml create mode 100644 xmldoc/filters/options/track-pack.xml create mode 100644 xmldoc/filters/options/track-sdistance.xml create mode 100644 xmldoc/filters/options/track-speed.xml create mode 100644 xmldoc/filters/options/track-split.xml create mode 100644 xmldoc/filters/options/track-start.xml create mode 100644 xmldoc/filters/options/track-stop.xml create mode 100644 xmldoc/filters/options/track-title.xml create mode 100644 xmldoc/filters/polygon.xml create mode 100644 xmldoc/filters/position.xml create mode 100644 xmldoc/filters/radius.xml create mode 100644 xmldoc/filters/reverse.xml create mode 100644 xmldoc/filters/simplify.xml create mode 100644 xmldoc/filters/sort.xml create mode 100644 xmldoc/filters/stack.xml create mode 100644 xmldoc/filters/track.xml create mode 100644 xmldoc/filters/transform.xml create mode 100644 xmldoc/formats/an1.xml create mode 100644 xmldoc/formats/arc.xml create mode 100644 xmldoc/formats/axim_gpb.xml create mode 100644 xmldoc/formats/baroiq.xml create mode 100644 xmldoc/formats/bcr.xml create mode 100644 xmldoc/formats/cambridge.xml create mode 100644 xmldoc/formats/cetus.xml create mode 100644 xmldoc/formats/coastexp.xml create mode 100644 xmldoc/formats/compegps.xml create mode 100644 xmldoc/formats/copilot.xml create mode 100644 xmldoc/formats/coto.xml create mode 100644 xmldoc/formats/cst.xml create mode 100644 xmldoc/formats/csv.xml create mode 100644 xmldoc/formats/cup.xml create mode 100644 xmldoc/formats/custom.xml create mode 100644 xmldoc/formats/dmtlog.xml create mode 100644 xmldoc/formats/dna.xml create mode 100644 xmldoc/formats/easygps.xml create mode 100644 xmldoc/formats/fugawi.xml create mode 100644 xmldoc/formats/garmin.xml create mode 100644 xmldoc/formats/garmin301.xml create mode 100644 xmldoc/formats/garmin_poi.xml create mode 100644 xmldoc/formats/garmin_txt.xml create mode 100644 xmldoc/formats/gcdb.xml create mode 100644 xmldoc/formats/gdb.xml create mode 100644 xmldoc/formats/geo.xml create mode 100644 xmldoc/formats/geonet.xml create mode 100644 xmldoc/formats/geoniche.xml create mode 100644 xmldoc/formats/glogbook.xml create mode 100644 xmldoc/formats/google.xml create mode 100644 xmldoc/formats/gpilots.xml create mode 100644 xmldoc/formats/gpl.xml create mode 100644 xmldoc/formats/gpsdrive.xml create mode 100644 xmldoc/formats/gpsdrivetrack.xml create mode 100644 xmldoc/formats/gpsman.xml create mode 100644 xmldoc/formats/gpspilot.xml create mode 100644 xmldoc/formats/gpssim.xml create mode 100644 xmldoc/formats/gpsutil.xml create mode 100644 xmldoc/formats/gpx.xml create mode 100644 xmldoc/formats/gtm.xml create mode 100644 xmldoc/formats/gtrnctr.xml create mode 100644 xmldoc/formats/hiketech.xml create mode 100644 xmldoc/formats/holux.xml create mode 100644 xmldoc/formats/hsandv.xml create mode 100644 xmldoc/formats/html.xml create mode 100644 xmldoc/formats/igc.xml create mode 100644 xmldoc/formats/ignrando.xml create mode 100644 xmldoc/formats/kml.xml create mode 100644 xmldoc/formats/ktf2.xml create mode 100644 xmldoc/formats/kwf2.xml create mode 100644 xmldoc/formats/lowranceusr.xml create mode 100644 xmldoc/formats/mag_pdb.xml create mode 100644 xmldoc/formats/magellan.xml create mode 100644 xmldoc/formats/magellan1.xml create mode 100644 xmldoc/formats/magellanx.xml create mode 100644 xmldoc/formats/maggeo.xml create mode 100644 xmldoc/formats/magnav.xml create mode 100644 xmldoc/formats/mapconverter.xml create mode 100644 xmldoc/formats/mapsend.xml create mode 100644 xmldoc/formats/mapsource.xml create mode 100644 xmldoc/formats/msroute.xml create mode 100644 xmldoc/formats/msroute1.xml create mode 100644 xmldoc/formats/mxf.xml create mode 100644 xmldoc/formats/navicache.xml create mode 100644 xmldoc/formats/netstumbler.xml create mode 100644 xmldoc/formats/nima.xml create mode 100644 xmldoc/formats/nmea.xml create mode 100644 xmldoc/formats/nmn4.xml create mode 100644 xmldoc/formats/openoffice.xml create mode 100644 xmldoc/formats/options/an1-color.xml create mode 100644 xmldoc/formats/options/an1-deficon.xml create mode 100644 xmldoc/formats/options/an1-nogc.xml create mode 100644 xmldoc/formats/options/an1-radius.xml create mode 100644 xmldoc/formats/options/an1-road.xml create mode 100644 xmldoc/formats/options/an1-type.xml create mode 100644 xmldoc/formats/options/an1-wpt_type.xml create mode 100644 xmldoc/formats/options/an1-zoom.xml create mode 100644 xmldoc/formats/options/bcr-index.xml create mode 100644 xmldoc/formats/options/bcr-name.xml create mode 100644 xmldoc/formats/options/bcr-radius.xml create mode 100644 xmldoc/formats/options/cetus-appendicon.xml create mode 100644 xmldoc/formats/options/cetus-dbname.xml create mode 100644 xmldoc/formats/options/compegps-deficon.xml create mode 100644 xmldoc/formats/options/compegps-index.xml create mode 100644 xmldoc/formats/options/compegps-radius.xml create mode 100644 xmldoc/formats/options/compegps-snlen.xml create mode 100644 xmldoc/formats/options/coto-zerocat.xml create mode 100644 xmldoc/formats/options/dmtlog-index.xml create mode 100644 xmldoc/formats/options/garmin-category.xml create mode 100644 xmldoc/formats/options/garmin-deficon.xml create mode 100644 xmldoc/formats/options/garmin-get_posn.xml create mode 100644 xmldoc/formats/options/garmin-power_off.xml create mode 100644 xmldoc/formats/options/garmin-snlen.xml create mode 100644 xmldoc/formats/options/garmin-snwhite.xml create mode 100644 xmldoc/formats/options/garmin_txt-date.xml create mode 100644 xmldoc/formats/options/garmin_txt-datum.xml create mode 100644 xmldoc/formats/options/garmin_txt-dist.xml create mode 100644 xmldoc/formats/options/garmin_txt-prec.xml create mode 100644 xmldoc/formats/options/garmin_txt-temp.xml create mode 100644 xmldoc/formats/options/garmin_txt-time.xml create mode 100644 xmldoc/formats/options/garmin_txt-utc.xml create mode 100644 xmldoc/formats/options/gdb-cat.xml create mode 100644 xmldoc/formats/options/gdb-ver.xml create mode 100644 xmldoc/formats/options/gdb-via.xml create mode 100644 xmldoc/formats/options/geo-deficon.xml create mode 100644 xmldoc/formats/options/geo-nuke_placer.xml create mode 100644 xmldoc/formats/options/geoniche-category.xml create mode 100644 xmldoc/formats/options/geoniche-dbname.xml create mode 100644 xmldoc/formats/options/gpilots-dbname.xml create mode 100644 xmldoc/formats/options/gpspilot-dbname.xml create mode 100644 xmldoc/formats/options/gpssim-split.xml create mode 100644 xmldoc/formats/options/gpssim-wayptspd.xml create mode 100644 xmldoc/formats/options/gpx-gpxver.xml create mode 100644 xmldoc/formats/options/gpx-logpoint.xml create mode 100644 xmldoc/formats/options/gpx-snlen.xml create mode 100644 xmldoc/formats/options/gpx-suppresswhite.xml create mode 100644 xmldoc/formats/options/gpx-urlbase.xml create mode 100644 xmldoc/formats/options/html-altunits.xml create mode 100644 xmldoc/formats/options/html-degformat.xml create mode 100644 xmldoc/formats/options/html-encrypt.xml create mode 100644 xmldoc/formats/options/html-logs.xml create mode 100644 xmldoc/formats/options/html-stylesheet.xml create mode 100644 xmldoc/formats/options/igc-timeadj.xml create mode 100644 xmldoc/formats/options/ignrando-index.xml create mode 100644 xmldoc/formats/options/kml-deficon.xml create mode 100644 xmldoc/formats/options/kml-extrude.xml create mode 100644 xmldoc/formats/options/kml-floating.xml create mode 100644 xmldoc/formats/options/kml-labels.xml create mode 100644 xmldoc/formats/options/kml-line_color.xml create mode 100644 xmldoc/formats/options/kml-line_width.xml create mode 100644 xmldoc/formats/options/kml-lines.xml create mode 100644 xmldoc/formats/options/kml-max_position_points.xml create mode 100644 xmldoc/formats/options/kml-points.xml create mode 100644 xmldoc/formats/options/kml-trackdata.xml create mode 100644 xmldoc/formats/options/kml-units.xml create mode 100644 xmldoc/formats/options/lowranceusr-break.xml create mode 100644 xmldoc/formats/options/lowranceusr-ignoreicons.xml create mode 100644 xmldoc/formats/options/lowranceusr-merge.xml create mode 100644 xmldoc/formats/options/magellan-deficon.xml create mode 100644 xmldoc/formats/options/magellan-maxcmts.xml create mode 100644 xmldoc/formats/options/magellan1-baud.xml create mode 100644 xmldoc/formats/options/magellan1-deficon.xml create mode 100644 xmldoc/formats/options/magellan1-maxcmts.xml create mode 100644 xmldoc/formats/options/magellan1-noack.xml create mode 100644 xmldoc/formats/options/magellan1-nukewpt.xml create mode 100644 xmldoc/formats/options/magellanx-deficon.xml create mode 100644 xmldoc/formats/options/magellanx-maxcmts.xml create mode 100644 xmldoc/formats/options/mapsend-trkver.xml create mode 100644 xmldoc/formats/options/mapsource-mpsmergeout.xml create mode 100644 xmldoc/formats/options/mapsource-mpsusedepth.xml create mode 100644 xmldoc/formats/options/mapsource-mpsuseprox.xml create mode 100644 xmldoc/formats/options/mapsource-mpsverout.xml create mode 100644 xmldoc/formats/options/mapsource-snlen.xml create mode 100644 xmldoc/formats/options/mapsource-snwhite.xml create mode 100644 xmldoc/formats/options/navicache-noretired.xml create mode 100644 xmldoc/formats/options/netstumbler-nseicon.xml create mode 100644 xmldoc/formats/options/netstumbler-nsneicon.xml create mode 100644 xmldoc/formats/options/netstumbler-seicon.xml create mode 100644 xmldoc/formats/options/netstumbler-sneicon.xml create mode 100644 xmldoc/formats/options/netstumbler-snmac.xml create mode 100644 xmldoc/formats/options/nmea-baud.xml create mode 100644 xmldoc/formats/options/nmea-date.xml create mode 100644 xmldoc/formats/options/nmea-get_posn.xml create mode 100644 xmldoc/formats/options/nmea-gpgga.xml create mode 100644 xmldoc/formats/options/nmea-gpgsa.xml create mode 100644 xmldoc/formats/options/nmea-gprmc.xml create mode 100644 xmldoc/formats/options/nmea-gpvtg.xml create mode 100644 xmldoc/formats/options/nmea-pause.xml create mode 100644 xmldoc/formats/options/nmea-snlen.xml create mode 100644 xmldoc/formats/options/nmn4-index.xml create mode 100644 xmldoc/formats/options/ozi-snlen.xml create mode 100644 xmldoc/formats/options/ozi-snunique.xml create mode 100644 xmldoc/formats/options/ozi-snupper.xml create mode 100644 xmldoc/formats/options/ozi-snwhite.xml create mode 100644 xmldoc/formats/options/ozi-wptbgcolor.xml create mode 100644 xmldoc/formats/options/ozi-wptfgcolor.xml create mode 100644 xmldoc/formats/options/palmdoc-bookmarks_short.xml create mode 100644 xmldoc/formats/options/palmdoc-dbname.xml create mode 100644 xmldoc/formats/options/palmdoc-encrypt.xml create mode 100644 xmldoc/formats/options/palmdoc-logs.xml create mode 100644 xmldoc/formats/options/palmdoc-nosep.xml create mode 100644 xmldoc/formats/options/pathaway-date.xml create mode 100644 xmldoc/formats/options/pathaway-dbname.xml create mode 100644 xmldoc/formats/options/pathaway-deficon.xml create mode 100644 xmldoc/formats/options/pathaway-snlen.xml create mode 100644 xmldoc/formats/options/pcx-cartoexploreur.xml create mode 100644 xmldoc/formats/options/pcx-deficon.xml create mode 100644 xmldoc/formats/options/quovadis-dbname.xml create mode 100644 xmldoc/formats/options/saroute-controls.xml create mode 100644 xmldoc/formats/options/saroute-split.xml create mode 100644 xmldoc/formats/options/saroute-times.xml create mode 100644 xmldoc/formats/options/saroute-turns_important.xml create mode 100644 xmldoc/formats/options/saroute-turns_only.xml create mode 100644 xmldoc/formats/options/stmsdf-index.xml create mode 100644 xmldoc/formats/options/stmwpp-index.xml create mode 100644 xmldoc/formats/options/tef-routevia.xml create mode 100644 xmldoc/formats/options/text-altunits.xml create mode 100644 xmldoc/formats/options/text-degformat.xml create mode 100644 xmldoc/formats/options/text-encrypt.xml create mode 100644 xmldoc/formats/options/text-logs.xml create mode 100644 xmldoc/formats/options/text-nosep.xml create mode 100644 xmldoc/formats/options/tiger-genurl.xml create mode 100644 xmldoc/formats/options/tiger-iconismarker.xml create mode 100644 xmldoc/formats/options/tiger-margin.xml create mode 100644 xmldoc/formats/options/tiger-newmarker.xml create mode 100644 xmldoc/formats/options/tiger-nolabels.xml create mode 100644 xmldoc/formats/options/tiger-oldmarker.xml create mode 100644 xmldoc/formats/options/tiger-oldthresh.xml create mode 100644 xmldoc/formats/options/tiger-snlen.xml create mode 100644 xmldoc/formats/options/tiger-suppresswhite.xml create mode 100644 xmldoc/formats/options/tiger-unfoundmarker.xml create mode 100644 xmldoc/formats/options/tiger-xpixels.xml create mode 100644 xmldoc/formats/options/tiger-ypixels.xml create mode 100644 xmldoc/formats/options/tpg-datum.xml create mode 100644 xmldoc/formats/options/vcard-encrypt.xml create mode 100644 xmldoc/formats/options/wbt-erase.xml create mode 100644 xmldoc/formats/options/wfff-ahcicon.xml create mode 100644 xmldoc/formats/options/wfff-ahoicon.xml create mode 100644 xmldoc/formats/options/wfff-aicicon.xml create mode 100644 xmldoc/formats/options/wfff-aioicon.xml create mode 100644 xmldoc/formats/options/wfff-snmac.xml create mode 100644 xmldoc/formats/options/xcsv-prefer_shortnames.xml create mode 100644 xmldoc/formats/options/xcsv-snlen.xml create mode 100644 xmldoc/formats/options/xcsv-snunique.xml create mode 100644 xmldoc/formats/options/xcsv-snupper.xml create mode 100644 xmldoc/formats/options/xcsv-snwhite.xml create mode 100644 xmldoc/formats/options/xcsv-style.xml create mode 100644 xmldoc/formats/options/xcsv-urlbase.xml create mode 100644 xmldoc/formats/options/yahoo-addrsep.xml create mode 100644 xmldoc/formats/ozi.xml create mode 100644 xmldoc/formats/palmdoc.xml create mode 100644 xmldoc/formats/pathaway.xml create mode 100644 xmldoc/formats/pcx.xml create mode 100644 xmldoc/formats/psitrex.xml create mode 100644 xmldoc/formats/psp.xml create mode 100644 xmldoc/formats/quovadis.xml create mode 100644 xmldoc/formats/s_and_t.xml create mode 100644 xmldoc/formats/saplus.xml create mode 100644 xmldoc/formats/saroute.xml create mode 100644 xmldoc/formats/sportsim.xml create mode 100644 xmldoc/formats/stmsdf.xml create mode 100644 xmldoc/formats/stmwpp.xml create mode 100644 xmldoc/formats/tabsep.xml create mode 100644 xmldoc/formats/tef.xml create mode 100644 xmldoc/formats/text.xml create mode 100644 xmldoc/formats/tiger.xml create mode 100644 xmldoc/formats/tmpro.xml create mode 100644 xmldoc/formats/tomtom.xml create mode 100644 xmldoc/formats/tpg.xml create mode 100644 xmldoc/formats/tpo.xml create mode 100644 xmldoc/formats/tpo2.xml create mode 100644 xmldoc/formats/tpo3.xml create mode 100644 xmldoc/formats/unicsv.xml create mode 100644 xmldoc/formats/vcard.xml create mode 100644 xmldoc/formats/vitosmt.xml create mode 100644 xmldoc/formats/wbt-bin.xml create mode 100644 xmldoc/formats/wbt.xml create mode 100644 xmldoc/formats/wfff.xml create mode 100644 xmldoc/formats/xcsv.xml create mode 100644 xmldoc/formats/xmap.xml create mode 100644 xmldoc/formats/xmap2006.xml create mode 100644 xmldoc/formats/xmapwpt.xml create mode 100644 xmldoc/formats/yahoo.xml create mode 100644 xmldoc/gpsbabel_man.xml create mode 100644 xmldoc/makedoc.in create mode 100644 xmldoc/old/extract create mode 100644 xmldoc/old/extract.xsl create mode 100644 xmldoc/old/readme.xml create mode 100644 xmldoc/readme.xml create mode 100644 yahoo.c create mode 100644 zlib/ChangeLog create mode 100644 zlib/FAQ create mode 100644 zlib/Makefile.in.zlib create mode 100644 zlib/README create mode 100644 zlib/README.gpsbabel create mode 100644 zlib/adler32.c create mode 100644 zlib/algorithm.txt create mode 100644 zlib/compress.c create mode 100644 zlib/crc32.c create mode 100644 zlib/crc32.h create mode 100644 zlib/deflate.c create mode 100644 zlib/deflate.h create mode 100644 zlib/empty.in create mode 100644 zlib/gzio.c create mode 100644 zlib/infback.c create mode 100644 zlib/inffast.c create mode 100644 zlib/inffast.h create mode 100644 zlib/inffixed.h create mode 100644 zlib/inflate.c create mode 100644 zlib/inflate.h create mode 100644 zlib/inftrees.c create mode 100644 zlib/inftrees.h create mode 100644 zlib/trees.c create mode 100644 zlib/trees.h create mode 100644 zlib/uncompr.c create mode 100644 zlib/zconf.h create mode 100644 zlib/zconf.in.h create mode 100644 zlib/zlib.3 create mode 100644 zlib/zlib.h create mode 100644 zlib/zutil.c create mode 100644 zlib/zutil.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..1ad113d95 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,58 @@ +Authors, the people behind GPSBabel + +Chief Babel-Head: + +* Robert Lipe + +Major contributors: + +* Alex Mottram +* Olaf Klein +* Ronald L. Parker + +Other contributors and helpers: + +* Alan Bleasby +* Andrew Arensburger +* Andrew Kirmse +* Andy Armstrong +* Bernhard Spinnler +* Bruce Thompson +* Chris Jones +* Claus Broch +* Curtis E. Mills +* Dave Pawson +* Eric Cloninger +* Etienne Tasse +* Frank Warmerdam +* Fredie Kern +* Gary Paulson +* Gustavo Niemeyer +* Harald Nordius +* HSA Systems, Sven Dowideit +* Jason Rust +* Jeff Kalikstein +* Jeremy Atherton +* Jim Bensman +* Jochen Becker +* John Temples +* Josh McKee +* Justin Broughton +* Kjeld Jensen +* Mark Bradley +* Oyvind Kaurstad +* P. Rosen +* Pasha Phares +* Patrick Ohly +* Paul Fox +* Paul Merchant +* Paul Tomblin +* Richard Messeder +* Rick Richardson +* Robert Shaw +* Scott Brynen +* Steve Chamberlin +* Sven Dovideit +* Tim Zickus +* Tobias Minich +* Vladimir Nadvornik diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index f00532be1..000000000 --- a/ChangeLog +++ /dev/null @@ -1,17 +0,0 @@ -Version 1.0.0 - - NEW: Windows support. You must download and install the expat dll - if you do not already have it. Get it from - http://sourceforge.net/projects/mingwrep/ - NEW: '-s' can be used to synthesize shortnames. Handy for geocaching. - NEW: Read and write files for Meridian flash cards. - NEW: Add Cetus support. - NEW: Add partial Gpspilot support. - - FIXED: Bad math in gpsutil. - FIXED: Bad math in Magellan. - FIXED: Various minor bugs. - -Version 0.8.1 - - initial release diff --git a/Makefile b/Makefile deleted file mode 100644 index c181d7ec2..000000000 --- a/Makefile +++ /dev/null @@ -1,366 +0,0 @@ -VERSIONU=1_2_7-beta08252005 -VERSIOND=1.2.7-beta08252005 -VERSIONU=1_2_7 -VERSIOND=1.2.7 - -# If you do not have libexpat and you have no use for reading any input -# type that is XML-ish (i.e. gpx or geocaching.com's/loc) you can uncomment -# INHIBIT_EXPAT and coment out LIBEXPAT on just to get a build working quickly. -# INHIBIT_EXPAT=-DNO_EXPAT -LIBEXPAT=-lexpat # -lefence - -# USB may required non-standard libraries (like libusb) be installed -# and may not be available on all OSes. Uncomment this to remove the key -# parts of USB from the build. -LIBUSB=-lusb - -# Space is significant, because MSVC wants no space between switch and arg (-Fofoo.o) -# but cc/gcc does: -# $(OUTPUT_SWITCH)main.o -# becomes -o main.o (gcc) -# or -Fomain.o (cl.exe) -OUTPUT_SWITCH=-o # - -# -# Enable either or both of these as you wish. -# -OPTIMIZATION=-O $(EXTRA_OPTIMIZATION) -DEBUGGING=-g $(EXTRA_DEBUGGING) -# add -DDEBUG_MEM to turn on memory allocation logging -CFLAGS=$(EXTRA_CFLAGS) $(DEBUGGING) -Icoldsync $(INHIBIT_EXPAT) $(INHIBIT_USB) $(OPTIMIZATION) -INSTALL_TARGETDIR=/usr/local/ - -FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \ - gpsutil.o pcx.o cetus.o copilot.o gpspilot.o magnav.o \ - psp.o holux.o garmin.o tmpro.o tpg.o \ - xcsv.o gcdb.o tiger.o internal_styles.o easygps.o quovadis.o \ - gpilots.o saroute.o navicache.o psitrex.o geoniche.o delgpl.o \ - ozi.o nmea.o text.o html.o palmdoc.o netstumbler.o hsa_ndv.o \ - igc.o brauniger_iq.o shape.o hiketech.o glogbook.o coastexp.o \ - vcf.o overlay.o kml.o google.o lowranceusr.o an1.o tomtom.o \ - tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o - -FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o stackfilter.o trackfilter.o discard.o - -OSJEEPS=jeeps/gpslibusb.o -JEEPS=jeeps/gpsapp.o jeeps/gpscom.o \ - jeeps/gpsmath.o jeeps/gpsmem.o \ - jeeps/gpsprot.o jeeps/gpsread.o \ - jeeps/gpsrqst.o jeeps/gpssend.o jeeps/gpsserial.o jeeps/gpsutil.o \ - jeeps/gpsusbread.o jeeps/gpsusbsend.o jeeps/gpsusbstub.o $(OSJEEPS) -# Extra modules in Jeeps that we don't use -# jeeps/gpsfmt.o jeeps/gpsinput.o jeeps/gpsproj.o - - -COLDSYNC=coldsync/util.o coldsync/pdb.o - -SHAPE=shapelib/shpopen.o shapelib/dbfopen.o - -LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \ - csv_util.o strptime.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \ - uuid.o formspec.o xmltag.o \ - $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(FMTS) $(FILTERS) -OBJS = main.o $(LIBOBJS) - -.c.o: - $(CC) -c $(CFLAGS) $< $(OUTPUT_SWITCH)$@ - -all: gpsbabel - -# -# Alternate makefile target for the case when you have no libusb and no -# need for Garmin/USB (60, 76C, VistaC, Quest, etc.) support. -# -usbfree: - make LIBUSB= INHIBIT_USB=-DNO_USB - -gpsbabel: $(OBJS) - $(CC) $(CFLAGS) $(OBJS) $(LIBEXPAT) $(LIBUSB) -lm $(OUTPUT_SWITCH)$@ - -main.o: - $(CC) -c $(CFLAGS) -DVERSION=\"$(VERSIOND)\" $< $(OUTPUT_SWITCH)$@ - -clean: - rm -f $(OBJS) gpsbabel gpsbabel.exe - -check: - ./testo - -torture: - ./testo - ./torture_test - -# -# This will only work on UNIX-like substances. -# -install: - install gpsbabel $(INSTALL_TARGETDIR)/bin - -# Nerdy release stuff that needs to work only on Linux. - -leaktest: - make EXTRA_CFLAGS=-DDEBUG_MEM - tools/cleardebug - ./testo - tools/memdebug | grep -v '^command line:' - -dep: - make clean && make CC="gcc -MMD" && cat *.d */*.d > /tmp/dep && rm *.d */*.d - (echo -n "internal_styles.c: mkstyle.sh " ; echo style/*.style ; /bin/echo -e '\t./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1)' ) >> /tmp/dep - echo Edit Makefile and bring in /tmp/dep - - -release: - cvs commit - ./chkdoc - make clean && cd mingw ; make clean - rm -fr gpsbabel-$(VERSIOND) - cvs tag -F gpsbabel_$(VERSIONU) - cvs export -r gpsbabel_$(VERSIONU) -d gpsbabel-$(VERSIOND) gpsbabel - tar czf /tmp/gpsbabel-$(VERSIOND).tar.gz gpsbabel-$(VERSIOND) - cd /tmp ; tar xzf gpsbabel-$(VERSIOND).tar.gz - touch /tmp/gpsbabel-$(VERSIOND)/internal_styles.c - cd /tmp/gpsbabel-$(VERSIOND)/mingw ; make - curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).tar.gz ftp://upload.sf.net/incoming/ - curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).zip ftp://upload.sf.net/incoming/ - -mac-usbfree: - make LIBEXPAT=/sw/lib/libexpat.a EXTRA_CFLAGS="-I/sw/include" LIBUSB= INHIBIT_USB=-DNO_USB - -mac-build: - make LIBEXPAT=/sw/lib/libexpat.a EXTRA_CFLAGS="-I/sw/include" LIBUSB="/sw/lib/libusb.a -lIOKit -lBSDPClient -framework CoreFoundation" - -mac-release: - mkdir -p usr/bin usr/share/gpsbabel/doc - cp gpsbabel usr/bin/ - cp README* COPYING usr/share/gpsbabel/doc - tar cvzf gpsbabel-osx.tgz usr/bin/gpsbabel - curl -u anonymous:anonymous --upload-file gpsbabel-osx.tgz ftp://upload.sf.net/incoming/ - -msvc-build: - make CC=@CL.EXE DEBUGGING="" EXTRA_CFLAGS="-nologo -W3 -WL -D__WIN32__ -I msvc/expat " OUTPUT_SWITCH="-Fo" $(OBJS) - echo $(OBJS) > objs.lst - LINK.EXE /NOLOGO @objs.lst ./msvc/expat/libexpat.lib /out:gpsbabel.exe - -# Machine generated from here down. -an1.o: an1.c defs.h queue.h gbtypes.h an1sym.h -arcdist.o: arcdist.c defs.h queue.h gbtypes.h grtcirc.h -bcr.o: bcr.c defs.h queue.h gbtypes.h garmin_tables.h -brauniger_iq.o: brauniger_iq.c defs.h queue.h gbtypes.h jeeps/gpsserial.h \ - jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -cetus.o: cetus.c defs.h queue.h gbtypes.h coldsync/palm.h coldsync/pdb.h -coastexp.o: coastexp.c defs.h queue.h gbtypes.h xmlgeneric.h uuid.h -copilot.o: copilot.c defs.h queue.h gbtypes.h coldsync/palm.h \ - coldsync/pdb.h -coto.o: coto.c defs.h queue.h gbtypes.h csv_util.h coldsync/palm.h \ - coldsync/pdb.h -csv_util.o: csv_util.c defs.h queue.h gbtypes.h csv_util.h grtcirc.h \ - strptime.h -delgpl.o: delgpl.c defs.h queue.h gbtypes.h -discard.o: discard.c defs.h queue.h gbtypes.h -duplicate.o: duplicate.c defs.h queue.h gbtypes.h -easygps.o: easygps.c defs.h queue.h gbtypes.h -filter_vecs.o: filter_vecs.c defs.h queue.h gbtypes.h -formspec.o: formspec.c defs.h queue.h gbtypes.h -garmin.o: garmin.c defs.h queue.h gbtypes.h jeeps/gps.h jeeps/../defs.h \ - jeeps/gpsport.h jeeps/gpsserial.h jeeps/gps.h jeeps/gpssend.h \ - jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ - jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \ - jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h garmin_tables.h -garmin_tables.o: garmin_tables.c garmin_tables.h -gcdb.o: gcdb.c defs.h queue.h gbtypes.h coldsync/palm.h coldsync/pdb.h -gdb.o: gdb.c defs.h queue.h gbtypes.h garmin_tables.h jeeps/gpsmath.h \ - jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -geo.o: geo.c defs.h queue.h gbtypes.h xmlgeneric.h -geoniche.o: geoniche.c defs.h queue.h gbtypes.h coldsync/palm.h \ - coldsync/pdb.h -glogbook.o: glogbook.c defs.h queue.h gbtypes.h xmlgeneric.h -google.o: google.c defs.h queue.h gbtypes.h xmlgeneric.h -gpilots.o: gpilots.c defs.h queue.h gbtypes.h coldsync/palm.h \ - coldsync/pdb.h garmin_tables.h -gpspilot.o: gpspilot.c defs.h queue.h gbtypes.h coldsync/palm.h \ - coldsync/pdb.h -gpsutil.o: gpsutil.c defs.h queue.h gbtypes.h magellan.h -gpx.o: gpx.c defs.h queue.h gbtypes.h xmlgeneric.h -grtcirc.o: grtcirc.c defs.h queue.h gbtypes.h -hiketech.o: hiketech.c defs.h queue.h gbtypes.h xmlgeneric.h -holux.o: holux.c defs.h queue.h gbtypes.h holux.h -hsa_ndv.o: hsa_ndv.c defs.h queue.h gbtypes.h -html.o: html.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \ - jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \ - jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ - jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \ - jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -igc.o: igc.c defs.h queue.h gbtypes.h -internal_styles.o: internal_styles.c defs.h queue.h gbtypes.h -kml.o: kml.c defs.h queue.h gbtypes.h xmlgeneric.h -lowranceusr.o: lowranceusr.c defs.h queue.h gbtypes.h -maggeo.o: maggeo.c defs.h queue.h gbtypes.h xmlgeneric.h magellan.h -magnav.o: magnav.c defs.h queue.h gbtypes.h coldsync/palm.h \ - coldsync/pdb.h -magproto.o: magproto.c defs.h queue.h gbtypes.h magellan.h -main.o: main.c defs.h queue.h gbtypes.h -mapsend.o: mapsend.c defs.h queue.h gbtypes.h mapsend.h magellan.h -mapsource.o: mapsource.c defs.h queue.h gbtypes.h garmin_tables.h -mkshort.o: mkshort.c defs.h queue.h gbtypes.h -navicache.o: navicache.c defs.h queue.h gbtypes.h -netstumbler.o: netstumbler.c defs.h queue.h gbtypes.h csv_util.h -nmea.o: nmea.c defs.h queue.h gbtypes.h -overlay.o: overlay.c defs.h queue.h gbtypes.h grtcirc.h -ozi.o: ozi.c defs.h queue.h gbtypes.h csv_util.h -palmdoc.o: palmdoc.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \ - jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \ - jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ - jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \ - jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h coldsync/palm.h coldsync/pdb.h -pathaway.o: pathaway.c defs.h queue.h gbtypes.h coldsync/palm.h \ - coldsync/pdb.h csv_util.h -pcx.o: pcx.c defs.h queue.h gbtypes.h garmin_tables.h -polygon.o: polygon.c defs.h queue.h gbtypes.h -position.o: position.c defs.h queue.h gbtypes.h grtcirc.h -psitrex.o: psitrex.c defs.h queue.h gbtypes.h garmin_tables.h -psp.o: psp.c defs.h queue.h gbtypes.h -queue.o: queue.c queue.h -quovadis.o: quovadis.c quovadis.h defs.h queue.h gbtypes.h \ - coldsync/palm.h coldsync/pdb.h -reverse_route.o: reverse_route.c defs.h queue.h gbtypes.h -route.o: route.c defs.h queue.h gbtypes.h -saroute.o: saroute.c defs.h queue.h gbtypes.h -shape.o: shape.c defs.h queue.h gbtypes.h shapelib/shapefil.h -smplrout.o: smplrout.c defs.h queue.h gbtypes.h grtcirc.h -sort.o: sort.c defs.h queue.h gbtypes.h -stackfilter.o: stackfilter.c defs.h queue.h gbtypes.h -strptime.o: strptime.c strptime.h -tef_xml.o: tef_xml.c defs.h queue.h gbtypes.h xmlgeneric.h -text.o: text.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \ - jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \ - jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ - jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \ - jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -tiger.o: tiger.c defs.h queue.h gbtypes.h csv_util.h -tmpro.o: tmpro.c defs.h queue.h gbtypes.h csv_util.h -tomtom.o: tomtom.c defs.h queue.h gbtypes.h -tpg.o: tpg.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \ - jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \ - jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ - jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \ - jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -trackfilter.o: trackfilter.c defs.h queue.h gbtypes.h strptime.h -util.o: util.c defs.h queue.h gbtypes.h -util_crc.o: util_crc.c -uuid.o: uuid.c uuid.h -vcf.o: vcf.c defs.h queue.h gbtypes.h jeeps/gpsmath.h jeeps/gps.h \ - jeeps/../defs.h jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h \ - jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ - jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h \ - jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ - jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -vecs.o: vecs.c defs.h queue.h gbtypes.h csv_util.h -vitosmt.o: vitosmt.c defs.h queue.h gbtypes.h -vmem.o: vmem.c defs.h queue.h gbtypes.h -waypt.o: waypt.c defs.h queue.h gbtypes.h -xcsv.o: xcsv.c defs.h queue.h gbtypes.h csv_util.h -xmlgeneric.o: xmlgeneric.c defs.h queue.h gbtypes.h xmlgeneric.h -xmltag.o: xmltag.c defs.h queue.h gbtypes.h -coldsync/pdb.o: coldsync/pdb.c coldsync/config.h coldsync/palm.h \ - coldsync/pdb.h -coldsync/util.o: coldsync/util.c coldsync/config.h coldsync/pconn/util.h \ - coldsync/palm.h -jeeps/gpsapp.o: jeeps/gpsapp.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -jeeps/gpscom.o: jeeps/gpscom.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -jeeps/gpslibusb.o: jeeps/gpslibusb.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h -jeeps/gpsmath.o: jeeps/gpsmath.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/gpsdatum.h -jeeps/gpsmem.o: jeeps/gpsmem.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h -jeeps/gpsprot.o: jeeps/gpsprot.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -jeeps/gpsread.o: jeeps/gpsread.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/gpsusbint.h -jeeps/gpsrqst.o: jeeps/gpsrqst.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -jeeps/gpssend.o: jeeps/gpssend.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/gpsusbint.h -jeeps/gpsserial.o: jeeps/gpsserial.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h -jeeps/gpsusbread.o: jeeps/gpsusbread.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h \ - jeeps/gpsusbint.h -jeeps/gpsusbsend.o: jeeps/gpsusbsend.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h jeeps/garminusb.h \ - jeeps/gpsusbint.h -jeeps/gpsusbstub.o: jeeps/gpsusbstub.c -jeeps/gpsutil.o: jeeps/gpsutil.c jeeps/gps.h jeeps/../defs.h \ - jeeps/../queue.h jeeps/../gbtypes.h jeeps/gpsport.h jeeps/gpsserial.h \ - jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ - jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ - jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ - jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h -shapelib/dbfopen.o: shapelib/dbfopen.c shapelib/shapefil.h -shapelib/shpopen.o: shapelib/shpopen.c shapelib/shapefil.h -internal_styles.c: mkstyle.sh style/README.style style/arc.style style/csv.style style/custom.style style/dna.style style/fugawi.style style/gpsdrive.style style/gpsdrivetrack.style style/gpsman.style style/mapconverter.style style/mxf.style style/nima.style style/openoffice.style style/s_and_t.style style/saplus.style style/tabsep.style style/xmap.style style/xmapwpt.style - ./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1) diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..fcfc1a08b --- /dev/null +++ b/Makefile.in @@ -0,0 +1,784 @@ +VPATH = @srcdir@ + +# version and release are defined in the head of configure.in +# don't forget 'autoconf' if you change them +VERSD=@GBMAJOR@.@GBMINOR@.@GBMICRO@ +VERSU=@GBMAJOR@_@GBMINOR@_@GBMICRO@ +RELEASE=@PACKAGE_RELEASE@ + +VERSIOND=$(VERSD)$(RELEASE) +VERSIONU=$(VERSU)$(RELEASE) + +DOCVERSION=development +DOCVERSION=@PACKAGE_VERSION@ + +CC=@CC@ +EXEEXT=@EXEEXT@ + +# Resource compiler, currently used under MinGW +RC=@RC@ + +#EXTRA_LIBS -lefence + +# Space is significant, because MSVC wants no space between switch and arg (-Fofoo.o) +# but cc/gcc does: +# $(OUTPUT_SWITCH)main.o +# becomes -o main.o (gcc) +# or -Fomain.o (cl.exe) +OUTPUT_SWITCH=-o # + +# +# Enable either or both of these as you wish. +# +#OPTIMIZATION=-O $(EXTRA_OPTIMIZATION) +#DEBUGGING=-g $(EXTRA_DEBUGGING) +# add -DDEBUG_MEM to turn on memory allocation logging +GBCFLAGS=$(EXTRA_CFLAGS) $(DEBUGGING) -I. -I@srcdir@/coldsync \ + $(OPTIMIZATION) @CFLAGS@ +LDFLAGS=$(EXTRA_LDFLAGS) @LDFLAGS@ +DESTDIR=/usr/local/ + +# OTHER_ROOT=/opt/local # For DarwinPorts on OSX +# OTHER_ROOT=/sw # Uncomment For Fink on OS X. + +FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \ + gtm.o \ + gpsutil.o pcx.o cetus.o copilot.o gpspilot.o magnav.o \ + psp.o holux.o garmin.o tmpro.o tpg.o tpo.o \ + xcsv.o gcdb.o tiger.o internal_styles.o easygps.o quovadis.o \ + gpilots.o saroute.o navicache.o psitrex.o geoniche.o delgpl.o \ + ozi.o nmea.o text.o html.o palmdoc.o netstumbler.o hsa_ndv.o \ + igc.o brauniger_iq.o shape.o hiketech.o glogbook.o coastexp.o \ + vcf.o overlay.o kml.o google.o lowranceusr.o an1.o tomtom.o \ + tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o \ + ignrando.o stmwpp.o msroute.o cst.o nmn4.o mag_pdb.o compegps.o \ + yahoo.o unicsv.o wfff_xml.o garmin_txt.o axim_gpb.o gpssim.o \ + wbt-200.o stmsdf.o gtrnctr.o dmtlog.o + +FILTERS=position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \ + reverse_route.o sort.o stackfilter.o trackfilter.o discard.o \ + nukedata.o interpolate.o transform.o + +JEEPS=jeeps/gpsapp.o jeeps/gpscom.o \ + jeeps/gpsmath.o jeeps/gpsmem.o \ + jeeps/gpsprot.o jeeps/gpsread.o \ + jeeps/gpsdevice.o jeeps/gpsdevice_ser.o jeeps/gpsdevice_usb.o \ + jeeps/gpsrqst.o jeeps/gpssend.o jeeps/gpsserial.o jeeps/gpsutil.o \ + jeeps/gpsusbread.o jeeps/gpsusbsend.o \ + jeeps/gpsusbcommon.o @OSJEEPS@ + +# Extra modules in Jeeps that we don't use +# jeeps/gpsfmt.o jeeps/gpsinput.o jeeps/gpsproj.o + + +COLDSYNC=coldsync/util.o coldsync/pdb.o + +SHAPE=shapelib/shpopen.o shapelib/dbfopen.o + +ZLIB=zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o \ + zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/trees.o \ + zlib/uncompr.o zlib/gzio.o zlib/zutil.o + +LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \ + csv_util.o strptime.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \ + uuid.o formspec.o xmltag.o cet.o cet_util.o fatal.o rgbcolors.o \ + inifile.o garmin_fs.o gbsleep.o units.o @GBSER@ gbser.o \ + gbfile.o \ + $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) @ZLIB@ $(FMTS) $(FILTERS) +OBJS = main.o globals.o $(LIBOBJS) @FILEINFO@ + +.c.o: + $(CC) @CPPFLAGS@ -c $(GBCFLAGS) $< $(OUTPUT_SWITCH)$@ + + + +# Directory of local web doc. Traditionally a sibling to the GPSBabel tree. +WEB=@DOCDIR@ + + +all: gpsbabel$(EXEEXT) + +gpsbabel$(EXEEXT): $(OBJS) @GPSBABEL_DEBUG@ Makefile configure + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) @LIBS@ @EXPAT_LIB@ @USB_LIBS@ $(OUTPUT_SWITCH)$@ + +gpsbabel-debug: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) @LIBS@ @EFENCE_LIB@ @EXPAT_LIB@ @USB_LIBS@ $(OUTPUT_SWITCH)$@ + +Makefile: Makefile.in config.status + CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +globals.o: + $(CC) @CPPFLAGS@ -c $(GBCFLAGS) -DVERSION=\"$(VERSIOND)\" $< $(OUTPUT_SWITCH)$@ + +jeeps/gpslibusb.o: + $(CC) @CPPFLAGS@ -c $(GBCFLAGS) @USB_CFLAGS@ @srcdir@/jeeps/gpslibusb.c $(OUTPUT_SWITCH)$@ + +fileinfo.o: win32/gpsbabel.rc + $(RC) -o fileinfo.o win32/gpsbabel.rc + +clean: + rm -f $(OBJS) gpsbabel gpsbabel.exe + +configure: configure.in + autoconf + +more-clean: clean + tools/mkmoreclean + +check: + ./testo + +torture: + ./testo + ./torture_test + +# +# This will only work on UNIX-like substances. +# +install: @INSTALL_DEBUG@ + install gpsbabel $(DESTDIR)/bin + +install-debug: + install gpsbabel-debug $(DESTDIR)/bin + +# Nerdy release stuff that needs to work only on Linux. + +leaktest: + make EXTRA_CFLAGS=-DDEBUG_MEM + tools/cleardebug + ./testo + tools/memdebug | grep -v '^command line:' + +dep: + make clean && make EXTRA_CFLAGS="-MMD" && cat *.d */*.d > /tmp/dep && rm *.d */*.d + (echo -n "internal_styles.c: mkstyle.sh " ; echo style/*.style ; /bin/echo -e '\t./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1)' ) >> /tmp/dep + echo Edit Makefile.in and bring in /tmp/dep + +$(WEB)/htmldoc-$(DOCVERSION)/readme.html: FORCE + perl xmldoc/makedoc + xmlwf xmldoc/readme.xml #check for well-formedness + xmllint --noout --valid xmldoc/readme.xml #validate + xsltproc \ + --stringparam base.dir "$(WEB)/htmldoc-$(DOCVERSION)/" \ + --stringparam root.filename "readme" \ + xmldoc/babelmain.xsl \ + xmldoc/readme.xml + chmod 755 tools/mkcapabilities + tools/mkcapabilities + +gpsbabel.html: FORCE + xsltproc \ + --stringparam toc.section.depth "1" \ + --stringparam html.stylesheet \ + "http://www.gpsbabel.org/style3.css" \ + http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl \ + xmldoc/readme.xml > $@ || rm $@ + +readme.txt: gpsbabel.html + lynx -nolist -dump gpsbabel.html > $@ + +doc: gpsbabel $(WEB)/htmldoc-$(DOCVERSION)/readme.html # readme.txt + +FORCE: + +# file list for windows package +WINFILES = gpsbabel.exe mingw/libexpat.dll win32/GPSBabelGUI.exe win32/gui-2/README.gui \ + README* AUTHORS COPYING gpsbabel.html + +# +# Do administrative-y things to the tree. Verify that everything is checked +# in and tagged. +# +release-sourcecheck: + cvs commit + ./chkdoc + make clean + rm -fr gpsbabel-$(VERSIOND) +#rjl make gpsbabel doc gpsbabel.html + @(. tools/functions && ask "Enter 'y' to tag the tree." "y") && cvs tag -F gpsbabel_$(VERSIONU) ; exit 0 + cvs export -r gpsbabel_$(VERSIONU) -d gpsbabel-$(VERSIOND) gpsbabel + touch gpsbabel-$(VERSIOND)/internal_styles.c + +# +# Build the release tarball from the exported CVS tree, tweaking +# timestamps and including generated filess as needed. +# +release-tarball: gpsbabel.html +# rm -fr gpsbabel-$(VERSIOND) + cp -ap gpsbabel.html gpsbabel-$(VERSIOND)/ + tar czf /tmp/gpsbabel-$(VERSIOND).tar.gz gpsbabel-$(VERSIOND) +# cd /tmp ; tar xzf gpsbabel-$(VERSIOND).tar.gz + +release-rpm: + test -f gpsbabel.html + mkdir -p /tmp/dist/BUILD \ + /tmp/dist/RPMS /tmp/dist/SPECS \ + /tmp/dist/SOURCES /tmp/dist/SRPMS \ + /tmp/dist/TMP /tmp/dist/install + tools/mkspec $(WEB) $(VERSD) $(RELEASE) > /tmp/dist/SPECS/gpsbabel.spec + cp -ap gpsbabel.html gpsbabel-$(VERSIOND)/ + cp -ap CHANGELOG gpsbabel-$(VERSIOND)/ + rm -rf /tmp/dist/TMP/gpsbabel-$(VERSD) + rm -rf /tmp/dist/SOURCES/gpsbabel-$(VERSD).tgz + cp -apr gpsbabel-$(VERSIOND) /tmp/dist/TMP/gpsbabel-$(VERSD) + cd /tmp/dist/TMP ; tar --owner=0 --group=0 -czf ../SOURCES/gpsbabel-$(VERSD).tgz gpsbabel-$(VERSD) + rpmbuild -ba \ + --define "_topdir /tmp/dist" \ + --define "buildroot /tmp/dist/install" \ + /tmp/dist/SPECS/gpsbabel.spec + + +# +# The Windows executables are cross compiled from the exported CVS image. +# Do the build of that here and make a zip file for distribution. +# Do this build in a temporary tree that was a copy of the tagged one +# to avoid scribbling in the "real" one. +# +release-winbuild: + rm -fr /tmp/gpsbabel-$(VERSIOND)-cross + cp -a gpsbabel-$(VERSIOND) /tmp/gpsbabel-$(VERSIOND)-cross + cd /tmp/gpsbabel-$(VERSIOND)-cross ; \ + CC=i386-mingw32-gcc LDFLAGS="-s" ./configure --host=i386-pc-mingw32 --with-cet=all --with-expathdr=mingw/include --with-libexpat=mingw/lib && make && \ + zip -j /tmp/gpsbabel-$(VERSIOND).zip $(WINFILES) + rm -fr /tmp/gpsbabel-$(VERSIOND)-cross + +release-upload: /tmp/gpsbabel-$(VERSIOND).tar.gz /tmp/gpsbabel-$(VERSIOND).zip /tmp/dist/SRPMS/gpsbabel-$(VERSIOND)-0.src.rpm /tmp/dist/RPMS/i386/gpsbabel-$(VERSIOND)-0.i386.rpm + @(. tools/functions && ask "Type yes if you want to do the upload now" "yes" ) + curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).tar.gz ftp://upload.sf.net/incoming/ + curl -u anonymous:anonymous --upload-file /tmp/gpsbabel-$(VERSIOND).zip ftp://upload.sf.net/incoming/ + curl -u anonymous:anonymous --upload-file /tmp/dist/SRPMS/gpsbabel-$(VERSIOND)-0.src.rpm ftp://upload.sf.net/incoming/ + curl -u anonymous:anonymous --upload-file /tmp/dist/RPMS/i386/gpsbabel-$(VERSIOND)-0.i386.rpm ftp://upload.sf.net/incoming/ + +release: release-sourcecheck release-tarball release-winbuild release-rpm release-upload + +rpm: clean + tools/mkrpm $(VERSD) $(RELEASE) + +mac-release: + mkdir -p usr/bin usr/share/gpsbabel/doc + cp gpsbabel usr/bin/ + cp README* COPYING usr/share/gpsbabel/doc + tar cvzf gpsbabel-osx.tgz usr/bin/gpsbabel + curl -u anonymous:anonymous --upload-file gpsbabel-osx.tgz ftp://upload.sf.net/incoming/ + +msvc-build: + make CC=@CL.EXE DEBUGGING="" EXTRA_CFLAGS="-nologo -W3 -WL -D__WIN32__ -I msvc/expat " OUTPUT_SWITCH="-Fo" $(OBJS) + echo $(OBJS) > objs.lst + LINK.EXE /NOLOGO @objs.lst ./msvc/expat/libexpat.lib /out:gpsbabel.exe + +# Machine generated from here down. +an1.o: an1.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h an1sym.h +arcdist.o: arcdist.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +axim_gpb.o: axim_gpb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +bcr.o: bcr.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h garmin_tables.h +brauniger_iq.o: brauniger_iq.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h +cet.o: cet.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +cetus.o: cetus.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h +cet_util.o: cet_util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h cet/iso_8859_1.h \ + cet/iso_8859_15.h cet/ansi_x3_4_1968.h cet/cp1252.h cet/iso_8859_2.h \ + cet/cp1250.h cet/latin_greek_1.h cet/macintosh.h cet/cp1251.h \ + cet/cp1253.h cet/cp1254.h cet/cp1255.h cet/cp1256.h cet/cp1257.h \ + cet/ibm437.h cet/ibm850.h cet/ibm851.h cet/ibm852.h cet/ibm855.h \ + cet/ibm857.h cet/ibm860.h cet/ibm861.h cet/ibm862.h cet/ibm863.h \ + cet/ibm864.h cet/ibm865.h cet/ibm868.h cet/ibm869.h cet/iso_8859_10.h \ + cet/iso_8859_13.h cet/iso_8859_14.h cet/iso_8859_3.h cet/iso_8859_4.h \ + cet/iso_8859_5.h cet/iso_8859_6.h cet/iso_8859_7.h cet/iso_8859_8.h \ + cet/iso_8859_9.h cet/koi8_r.h cet/koi8_ru.h cet/koi_8.h +coastexp.o: coastexp.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h uuid.h +compegps.o: compegps.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +copilot.o: copilot.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h grtcirc.h +coto.o: coto.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h grtcirc.h +cst.o: cst.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h strptime.h +csv_util.o: csv_util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h grtcirc.h \ + strptime.h +delgpl.o: delgpl.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +discard.o: discard.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +dmtlog.o: dmtlog.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + xmlgeneric.h +duplicate.o: duplicate.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +easygps.o: easygps.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +fatal.o: fatal.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +filter_vecs.o: filter_vecs.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h +formspec.o: formspec.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +garmin.o: garmin.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gps.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + garmin_tables.h garmin_fs.h +garmin_fs.o: garmin_fs.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h garmin_tables.h +garmin_tables.o: garmin_tables.c garmin_tables.h defs.h config.h queue.h \ + gbtypes.h zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +garmin_txt.o: garmin_txt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h garmin_tables.h grtcirc.h jeeps/gpsmath.h strptime.h +gbfile.o: gbfile.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +gbser.o: gbser.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h \ + gbser_private.h +gbser_posix.o: gbser_posix.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h \ + gbser_private.h +gbsleep.o: gbsleep.c config.h +gcdb.o: gcdb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h +gdb.o: gdb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h garmin_tables.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + garmin_fs.h jeeps/gps.h +geo.o: geo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +geoniche.o: geoniche.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h garmin_tables.h +globals.o: globals.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +glogbook.o: glogbook.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +google.o: google.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +gpilots.o: gpilots.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h garmin_tables.h +gpspilot.o: gpspilot.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h +gpssim.o: gpssim.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +gpsutil.o: gpsutil.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h magellan.h +gpx.o: gpx.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h garmin_fs.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +grtcirc.o: grtcirc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +gtm.o: gtm.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +gtrnctr.o: gtrnctr.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +hiketech.o: hiketech.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +holux.o: holux.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h holux.h +hsa_ndv.o: hsa_ndv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +html.o: html.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +igc.o: igc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +ignrando.o: ignrando.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +inifile.o: inifile.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +internal_styles.o: internal_styles.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +interpolate.o: interpolate.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h grtcirc.h +kml.o: kml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +lowranceusr.o: lowranceusr.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +maggeo.o: maggeo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h \ + magellan.h +magnav.o: magnav.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h +mag_pdb.o: mag_pdb.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +magproto.o: magproto.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h magellan.h gbser.h +main.o: main.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h filterdefs.h csv_util.h +mapsend.o: mapsend.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h mapsend.h magellan.h +mapsource.o: mapsource.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_tables.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +mkshort.o: mkshort.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +msroute.o: msroute.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +navicache.o: navicache.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +netstumbler.o: netstumbler.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +nmea.o: nmea.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h gbser.h strptime.h +nmn4.o: nmn4.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +nukedata.o: nukedata.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +overlay.o: overlay.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +ozi.o: ozi.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +palmdoc.o: palmdoc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h \ + jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \ + jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \ + jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \ + jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h \ + coldsync/palm.h coldsync/../gbtypes.h coldsync/pdb.h +pathaway.o: pathaway.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h coldsync/palm.h \ + coldsync/../gbtypes.h coldsync/pdb.h csv_util.h strptime.h +pcx.o: pcx.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h garmin_tables.h +polygon.o: polygon.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +position.o: position.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +psitrex.o: psitrex.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h garmin_tables.h +psp.o: psp.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h grtcirc.h +queue.o: queue.c queue.h +quovadis.o: quovadis.c quovadis.h defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + coldsync/palm.h coldsync/../gbtypes.h coldsync/pdb.h +radius.o: radius.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +reverse_route.o: reverse_route.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h +rgbcolors.o: rgbcolors.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +route.o: route.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +saroute.o: saroute.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +shape.o: shape.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h shapelib/shapefil.h +smplrout.o: smplrout.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h +sort.o: sort.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h filterdefs.h +stackfilter.o: stackfilter.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h +stmsdf.o: stmsdf.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h strptime.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h grtcirc.h +stmwpp.o: stmwpp.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +strptime.o: strptime.c strptime.h +tef_xml.o: tef_xml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +text.o: text.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +tiger.o: tiger.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +tmpro.o: tmpro.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h +tomtom.o: tomtom.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +tpg.o: tpg.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +tpo.o: tpo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +trackfilter.o: trackfilter.c defs.h config.h queue.h gbtypes.h \ + zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \ + filterdefs.h strptime.h grtcirc.h +transform.o: transform.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h +unicsv.o: unicsv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h csv_util.h \ + jeeps/gpsmath.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \ + jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ + jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ + jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ + jeeps/gpsproj.h +units.o: units.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +util_crc.o: util_crc.c +util.o: util.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +uuid.o: uuid.c uuid.h +vcf.o: vcf.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h jeeps/gpsmath.h jeeps/gps.h \ + jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \ + jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \ + jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h +vecs.o: vecs.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +vitosmt.o: vitosmt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h grtcirc.h +vmem.o: vmem.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h +waypt.o: waypt.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +wbt-200.o: wbt-200.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h gbser.h grtcirc.h +wfff_xml.o: wfff_xml.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +xcsv.o: xcsv.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \ + gbfile.h cet.h cet_util.h inifile.h csv_util.h +xmlgeneric.o: xmlgeneric.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +xmltag.o: xmltag.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h +yahoo.o: yahoo.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \ + zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h xmlgeneric.h +coldsync/pdb.o: coldsync/pdb.c config.h coldsync/cs-config.h \ + coldsync/palm.h coldsync/../gbtypes.h coldsync/pdb.h +coldsync/util.o: coldsync/util.c config.h coldsync/cs-config.h \ + coldsync/pconn/util.h coldsync/palm.h coldsync/../gbtypes.h +jeeps/gpsapp.o: jeeps/gpsapp.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h +jeeps/gpscom.o: jeeps/gpscom.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpsdevice.o: jeeps/gpsdevice.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsdevice_ser.o: jeeps/gpsdevice_ser.c jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/../defs.h jeeps/../config.h jeeps/../queue.h \ + jeeps/../gbtypes.h jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h \ + jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h \ + jeeps/../inifile.h jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsdevice_usb.o: jeeps/gpsdevice_usb.c jeeps/gpsdevice.h \ + jeeps/gps.h jeeps/../defs.h jeeps/../config.h jeeps/../queue.h \ + jeeps/../gbtypes.h jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h \ + jeeps/../gbfile.h jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h \ + jeeps/../inifile.h jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h \ + jeeps/gpsusbcommon.h +jeeps/gpslibusb.o: jeeps/gpslibusb.c config.h jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbcommon.h +jeeps/gpsmath.o: jeeps/gpsmath.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsdatum.h +jeeps/gpsmem.o: jeeps/gpsmem.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpsprot.o: jeeps/gpsprot.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpsread.o: jeeps/gpsread.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsrqst.o: jeeps/gpsrqst.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +jeeps/gpssend.o: jeeps/gpssend.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h +jeeps/gpsserial.o: jeeps/gpsserial.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsserial.h jeeps/../gbser.h +jeeps/gpsusbcommon.o: jeeps/gpsusbcommon.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbcommon.h +jeeps/gpsusbread.o: jeeps/gpsusbread.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h +jeeps/gpsusbsend.o: jeeps/gpsusbsend.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/garminusb.h jeeps/gpsusbint.h +jeeps/gpsutil.o: jeeps/gpsutil.c jeeps/gps.h jeeps/../defs.h \ + jeeps/../config.h jeeps/../queue.h jeeps/../gbtypes.h \ + jeeps/../zlib/zlib.h jeeps/../zlib/zconf.h jeeps/../gbfile.h \ + jeeps/../defs.h jeeps/../cet.h jeeps/../cet_util.h jeeps/../inifile.h \ + jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \ + jeeps/gpsinput.h jeeps/gpsproj.h +shapelib/dbfopen.o: shapelib/dbfopen.c shapelib/shapefil.h config.h +shapelib/shpopen.o: shapelib/shpopen.c shapelib/shapefil.h config.h +zlib/adler32.o: zlib/adler32.c zlib/zlib.h zlib/zconf.h +zlib/compress.o: zlib/compress.c zlib/zlib.h zlib/zconf.h +zlib/crc32.o: zlib/crc32.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/crc32.h +zlib/deflate.o: zlib/deflate.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \ + zlib/zconf.h +zlib/gzio.o: zlib/gzio.c zlib/zutil.h zlib/zlib.h zlib/zconf.h +zlib/infback.o: zlib/infback.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h +zlib/inffast.o: zlib/inffast.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h zlib/inflate.h zlib/inffast.h +zlib/inflate.o: zlib/inflate.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h zlib/inflate.h zlib/inffast.h zlib/inffixed.h +zlib/inftrees.o: zlib/inftrees.c zlib/zutil.h zlib/zlib.h zlib/zconf.h \ + zlib/inftrees.h +zlib/trees.o: zlib/trees.c zlib/deflate.h zlib/zutil.h zlib/zlib.h \ + zlib/zconf.h zlib/trees.h +zlib/uncompr.o: zlib/uncompr.c zlib/zlib.h zlib/zconf.h +zlib/zutil.o: zlib/zutil.c zlib/zutil.h zlib/zlib.h zlib/zconf.h +internal_styles.c: mkstyle.sh style/arc.style style/cambridge.style style/csv.style style/cup.style style/custom.style style/dna.style style/fugawi.style style/garmin301.style style/garmin_poi.style style/geonet.style style/gpsdrive.style style/gpsdrivetrack.style style/gpsman.style style/ktf2.style style/kwf2.style style/mapconverter.style style/mxf.style style/nima.style style/openoffice.style style/s_and_t.style style/saplus.style style/sportsim.style style/tabsep.style style/xmap2006.style style/xmap.style style/xmapwpt.style + ./mkstyle.sh > internal_styles.c || (rm -f internal_styles.c ; exit 1) diff --git a/README b/README deleted file mode 100644 index d858f61bc..000000000 --- a/README +++ /dev/null @@ -1,1416 +0,0 @@ - -THE PROBLEM - - There are simply too many gratuitously different file formats to - hold waypoint, track, and route information in various programs - used by computers. GPX (http://www.topografix.com/gpx.asp) - defines a standard in XML to contain all the data, but there - are too many programs that don't understand it yet and - too much data that are in an alternate formats. - -THE SOLUTION - - I needed to convert waypoints between a couple of formats, so I - whipped up a converter and based it on an extensible foundation - so that it was easy to add new formats. Most file formats - added so far have taken under 200 lines of reasonable ISO C so - they can be stamped out pretty trivially. Formats that are - ASCII text delimited in some fixed way can be added with no - programming at all via our 'style' mechanism. - -GETTING IT / BUILDING IT - - GPSBabel is distributed in source format that will work on about - any operating system and as ready-to-run binaries for some - operating systems, notably Windows. See the "OS-Specific notes" - at http://www.gpsbabel.org for instructions on those - binary kits. - - For operating systems where no binary is provided, you will have - to build it. The code should be compilable on any system with - ISO C89 compilers. It's been tested on UnixWare, OpenServer, - OS/X, Linux, Solaris, and a variety of processors and compilers. - - Libexpat is required for source builds. If you get errors about - expat.h being missing, you must either edit the Makefile to tell - the compiler where it is or install it in a sensible place. - Exapt can be downloaded from http://expat.sourceforge.net and is - part of Apache so it's very portable. - -COMMON USAGE - - Invocation was meant to be flexible. Unfortunately, that can - sometimes lead to unwieldy command lines. - - gpsbabel -? - - will always show you the supported file types. To use this - program, just tell it what you're reading, where to read it from, - what you're writing, and what to write it to. For example: - - gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx - - tells it to read the first file in geocaching.com format and create - a new file in GPX format. - - This command will read from a Magellan unit attached to the first - serial port on a Linux system (device names will vary on other OSes) - and write them as a geocaching loc file. The second command does - the same for windows. - - gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc - gpsbabel -i magellan -f com1 -o geo -F mag.loc - - Optionally, you may specify "-s" in any command line. This causes - the program to ignore any "short" names that may be present in the - source data format and synthesize one from the long name. This - is particularly useful if you're writing to a target format that - isn't the lowest common denominator but the source data was written - for the lowest common denominator. I use this for writing data - from geocaching.com to my Magellan so my waypoints have "real" names - instead of the 'GC1234' ones that are optimized for NMEA-only - receivers. A geocacher with a Magellan receiver may thus find - commands like this useful. - - gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 - gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1 - -ADVANCED USAGE - - Argument are processed in the order they appear on the command line - and are translated internally into a pipeline that data flows - through when executed. Normally one would: - - read from one input - - optionally apply filters - - write into one output - - but GPSBabel is flexible enough to allow more complicated - operations such as reading from several files (potentially of - different types), applying a filter, reading more data, then - write the merged data to multiple destinations. - - The input file type remains unchanged until a new -i argument - is seen. Files are read in the order they appear. So you could - merge three input files into one output file with: - - gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc - - You can merge files of different types: - - gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps - - You can write the same data in different output formats: - - gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt - -ROUTE AND TRACK MODES - - Most formats will make reasonable attempt to work transparently - with waypoints, tracks, and routes. Some formats, like 'garmin' - and 'magellan' require the '-t' flag to work with tracks and - '-r' to work with routes. '-w' is for waypoints, and is the - default. So if you wanted to read all data from your unit into - a gpx file, you might use a command like: - - gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx - - Tracks and routes are advanced features and don't try to - handle every possible hazard that can be encountered during a - conversion. If you're merging or converting files of similar - limitations, things work very well. - - Tracks and routes will sometimes be converted to a list of - waypoints when necessary, f.i. when writing into one of the CSV - formats. The inverse operation is not supported right now, so - reading the converted track back from CSV will always result in - a list of waypoints, not the original track. - - The presence of "-s" on the command line tends to creats havoc - on tracks and routes since many of these formats rely on - internal linkages between such points and renaming them may - break those linkages. In general, don't use "-s" when tracks or - routes are present. - -THE FORMATS - - GPX - - This is the most capable and expressive of all the file formats - supplied. It is described at http://www.topografix.com/gpx.asp - and is supported by EasyGPS, ExpertGPS, and man other programs - described at http://www.topografix.com/gpx_resources.asp - - GEO - - geocaching.com spits up geocaching.loc files that are XML-ish but - not quite GPX. Becuase it's so close to GPX, this format is very - well supported. - - MAGELLAN - - Waypoint serial upload and download works reliably to the 315, 330, - Meridian, and SportTrak family. I expect it to work on any modern - Magellan unit. - - As of 08/30/02, GPSBabel can also read and write the files that - can be stuck on the SD memory cards with the Meridian models. - Simply specify a file instead of a serial port. - - Communication errors are handled robustly and verification of - data is enabled. - - Additional sub options: - baud: may be 1200, 2400, 4800, 9600, 19200, but must match receiver. - - MAGELLANX - - The SD card format used by the Magellan Explorist 400, 500, and 600. - It's identical to the Magellan SD format used by Meridian, but allows - longer waypoint names. - - You should name any file created with this format with a ".upt" - extension so the firmware can read it. - - MAGGEO - - The SD card format used by the Magellan Explorist 400, 500, and - 600 to describe geocaches. Notice what while the format can - hold an infinite number of geocaches, the unit will read and - silently discard all but 200 geocache POIs at a time. - - You should name any file created with this format with a ".gs" - extension so the firmware can read it. - - GARMIN - - Waypoint serial upload and download works reliably under both - POSIX and Windows. I originally tested it with a Vista, a - V, and a base eTrex, all graciously provided on loan by Joe - Armstrong, but it's now regularly exercised on a 60CS (USB and - serial) and many other models. The communications library used, - jeeps, claims to support most models of Garmin hardware. Be - sure the GPS is set for "Garmin mode" in setup and that nothing - else (PDA hotsync programs, gpsd, getty, pppd, etc.) is using - the serial port. - - GPSBabel supports the USB Garmins under Windows and on Linux and - OS/X via libusb. It's reported successful with VistaC, SummitC, - 60C, 60CS, 76C, 76CS, 96C, and Quest. Some users report success - with StreetPilot 2610 and some do not, but nobody's followed up - with details on that. - - Currently, only a single USB unit at a time can be supported. The - device name to use on the command line is "usb:" Thus, to read - the waypoints from a Garmin USB unit and write them to a GPX file: - - gpsbabel -i garmin -f usb: -o gpx -F blah.gpx - - When reporting problems with Garmin, be sure to include the full - unit model, firmware version, and be prepared to offer debugging - dumps by adding "-D9" to the command line, like: - - gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx - - Custom icons are supported on units that support that. Neither - GPSBabel nor your firmware know what is associated with any - given slot number. They don't know that the picture you placed - in the first slot is a happy face, they only know they're in the - lowest numbered slot. GPSBabel names the them consistently with - Mapsource, so they are named 'Custom 0' through 'Custom 23'. - - GPSMAN - - GPS Manager can read and write formats that this converter doesn't - understand. The default formats (WGS84, DDD) work reliably. - - GPSUTIL - - GPSUtil has a simple file format of this program that - runs on POSIX- compliant OSes like UNIX and Linux. - Reads and writes of this format are reliable. (I've - also contributed to this program.) It's available at - http://www.cs.uakron.edu/~hennings/gpsutil/. - - TIGER - - The U.S. Census Bureau proives online mapping facilities. This - format is described at: http://tiger.census.gov/instruct.html. - Do notice that this format is not the actual Tiger line mapping - records, but rather the interface to their online mapping program. - - CSV - - There are a billion variants of Comma Separated Value data. This - is the one that makes Delorme S&A Deluxe 9 happy. It's also a very - simple program and useful for many other programs like spreadsheets. - - CSV is also the correct format for Lowrance MapCreate, - their commercial mapping program, or GDM6 (their free - waypoint manager) for iFinder which is available at - http://www.lowrance.com/Software/GDM6/Default.asp - - LowranceUSR - - The Lowrance iFinder GPS series has the unique capability to - output its data to an MMC card. The data is saved to the card - as a .USR file and can be read by your computer using a card - reader. Waypoints, routes, tracks are supported. By default, - Event marker icons are converted to waypoints. Symbols tend - to get lost in the translation. - - Additional options: - ignoreicons - don't convert icons to waypoints - merge - (USR output) merge all tracks into a single - track with segments - break - (USR input) break track segments into separate - tracks - - XMap - - Delorme TopoUSA/XMap Conduit is one of the billion CSV variants - mentioned above. It's just like S&A with the addition of a - completely pointless line at the beginning and end of the file. - This is the format used to hot-sync to XMap from withing TopoUSA. - Done with help of Dan Edwards. - - XMapWpt - - Delorme XMapHandHeld Street Atlas USA is another of the billion - CSV variants. This is the format used by XmapHH SA USA on - (at least) PocketPC O/S. Please see README.xmapwpt for more - information on it's intricacies. This XMap is not to be confused - with the XMap mentioned above. Contributed to GPSBabel by - Alex Mottram. - - XCSV - - XCSV is an open-ended "Whatever Separated Values" parser / writer - designed to work with user-supplied "style" files. It should handle - at least a few thousand of the billion CSV variants available. - By itself, it doesn't comply to any format, however *most* CSV - variants can be described as a "style" and fine-tuned by the end - user. For more information on it's use, please see README.style - in the style/ sub-directory of GPSBabel. For an example of using - the XCSV module within your C program, look at the ozi.c, mxf.c, and - xmapwpt.c sources in the GPSBabel directory. This module was - contributed to GPSBabel by Alex Mottram. - - Additional Options: - style - **REQUIRED** Path to XCSV style file. - - snlen - Maximum length of synthesized shortnames. - snwhite - Switch defining whether or not to allow whitespace - in synthesized shortnames. - (0 = NO WHITESPACE, 1 = WHITESPACE OK). - snupper - Switch defining whether or not to force uppercase - in shortnames. (0 = LEAVE AS IS, 1 = UPPERCASE ALL). - - NOTE: sn* options require use of the '-s' command line option. - - Example Usage: - gpsbabel -i xcsv,style=foo.style -f foo -o xcsv,style=bar.style -F bar - gpsbabel -s -i gpx -f foo.gpx -o xcsv,style=my.style,snlen=8 -F bar - - MAPSEND - - Magellan was smart enough to document their file format to make - creating software like this possible. - - MAPSOURCE - - Garmin Mapsource format appears compatible with the various - members of that product family. Icon mapping is attempted - between different MapSource versions. Altitude is supported, - but proximity and depth are not. Naming files *.mps will - allow file->open in Mapsource to find the files more easily. - Versions 3, 4 and 5 of the Mapsource data format are handled - automatically on input and by default the output is version 5. - (Until 3/2004, it was version 3, but since Mapsource updates - are free, the convenience of having modern icon sets outweighs - the backward compatibility concern. Users of other versions - can either upgrade or specify the switches to get get output in - a compatible format.) Waypoints, routes and tracklogs are all - handled, but maps sets are ignored. - - Information on the Garmin Mapsource format was provided by Ian - Cowley and Mark Bradley. The code was implemented by Robert Lipe - and Mark Bradley. - - Additional options: - snlen - set the length of generated shortnames - mpsverout - set the data format version of the output file - (3,4 or 5) - mpsmergeout - if the output file already exists, then the output - is merged with it. This allows MapSource sections - not being handled to remain intact (e.g. map sets) - - PsiTrex - - This is a text format created by KuDaTa's PsiTrex program for - the Psion PDAs. The format can't be readily handled by XCSV, so - this format is handled explicitly. Waypoints, routes and tracks - are all handled, with icon names used corresponding to verison - 1.13 of PsiTrex. This module was contributed to GPSBabel by Mark - Bradley. - - PCX - - Garmin documents only PCX5, an older format limited to the - lame NMEA six-character waypoint names that's treated as a - second-class citizien in current versions of MapSource. In - Mapsource, use file->import to read these files. If you name - the files *.wpt, Mapsource will find them easier. - - In general, you should prefer the "mapsource" file format to - this one. - - CETUS - - Cetus GPS (http://www.cetusgps.dk/) is a program for Palm/OS. - Working with Ron Parker and Kjeld Jensen, we can now read and write - files for that program. - - QUOVADIS - - QuoVadis for Palm OS (http://www.marcosoft.com/) is a program - for Palm/OS. Working with record definitions provided by - MarcoSoft and further experimentation by Bruce Thompson and - "Fuzzy" from the Geocaching Forums to nail down the format - precisely. - - Should work fine for import and export. - - One thing of note, QuoVadis stores all waypoints in a single - Palm Database without using categories. This means that it may - be difficult to keep personal waypoints separate from - generated waypoints. What Bruce recommends is taking the - QuoVadisMarkerDB.PDB file synced down from your Palm Powered - device and extract the waypoints you personally set to a GPX - file. Then using GPSBabel's joining capabilities generate a - new PDB file from the personal file and the other waypoint - files of interest. - - Currently the selection of icons to display and the scale at - which to display them is hardcoded. Also there is no support - for notes associated with waypoints. This will be addressed in - a future revision. - - GPSPILOT - - The file format for GPSPILOT (http://www.gpspilot.com) was provided - by Ron Parker. The output from this module has been tested with - GPSPilot Tracker v5.05sx, but it is based on reverse-engineering - so it may not work with all versions of all GPSPilot products. - It had read-only support for Airport, Navaid, City and Landmark - files but will read and write Point files. - - MAGNAV - - Magellan NAV Companion for Palm/OS is not really designed for this - sort of use, but its file format is supported and with a little bit - of patience you can both read and write NAV Companion waypoints. - Please read README.magnav for further tips on getting waypoints - in and out of NAV Companion. This conversion is based on partially - incomplete reverse-engineering of the record format, so it may not - work with all versions of NAV Companion. It has been tested with - version 2.10 and 3.20. - - PSP - - Microsoft's PocketStreets 2002 Pushpin (.PSP) format is not yet - completely documented. THE .PSP MODULE DOES NOT WORK WITH MS - STREETS & TRIPS 2002 .EST FILES. To create .PSP files from - Streets & Trips 2002, you will need to have PocketStreets support - installed. Please note that MS Streets & Trips only *EXPORTS* - .PSP files. It does not import them. MS Streets & Trips 2002 - only imports CSV files. To use .PSP files, simply copy them - over to the same folder on the mobile device as the map (.MPS), - and open PocketStreets. It should also be noted that in the case - a pushpin is outside of the exported map area, the pin will be - "grayed-out" and unused in PocketStreets. This is a good thing - as it allows us to create one big .PSP file that covers multiple - .MPS files. Unfortunately, you need one .PSP file for every - .MPS file. :( - - MXF - - Maptech Exchange Format - Another CSV format file. This format - complies with (at least) Maptech Terrain Navigator, Terrain - Professional, Take a Hike, and ExpertGPS import/export MFX. - Contributed by Alex Mottram. - - DNA - - Navitrak DNA marker format - Another CSV format file. - This is the format that is compatible with the DNA Desktop - import/export command. Reading the binary Markers.jwp - format directly off the data card is not supported yet. - Contributed by Tim Zickus. - - OZI - - OziExplorer Waypoint Format - Another CSV format file. Tested - against OziExplorer v 3.90.3a / Shareware. Contributed by Alex - Mottram. - - TPG - - National Geographic Topo! Waypoint Format. This filter - reads and writes .TPG files created by various editions of NG Topo! - This filter will *not* work with the newer combined .TPO files. - Contributed by Alex Mottram. - - HOLUX - - The Holuxgm-100 (e-fox) gps receiver uses standard compact - flash cards. File formats were provided by Holux-Taiwan - http://www.holux.com.tw to the author. The code was tested - against version 2.27E1; other versions and receivers may - work but have not been explictly tested. Anyone with - information on other Holux receivers is encouraged to contact - jochen@bauerbahn.net. - - When copying the .wpo file to a flash card, the file must be - named "tempwprt.wpo" as the receiver will ignore all other - files. - - Comparing the waypoints of a .wpo files against other formats - like .gpx you may notice a small difference in the latitude - and longitude values. The reason is the low resolution of - the coordinates in the wpo file format. In a .wpo file the - reolution is 1/10"; in gpx for example it is 1/100". A a practical - matter, this loss is only about 1.7meters (5 feet). - - - The generated waypoint failes can also be used by MapShow - version 1.14. This program is free of charge from the Holux web - site. - - This format was contributed by Jochen Becker. - - TMPRO - - TopoMapPro Places File. Reads and writes places files for use - in TopoMapPro (http://www.topomappro.com). As this file type - can store links other than web links, anything that is not a - http url will be discarded. Note that this does not do datum - conversions, so if your input file does not have WGS84/NZGD2000 - data, your output file won't either. - Colour of waypoint icons defaults to red. - - GPSDRIVE - - GpsDrive way.txt file format. A space seperated format file. Tested - against GpsDrive v 1.30 found @ http://www.kraftvoll.at/software. - Contributed by Alan Curry. - - GPSDRIVETRACK - - Format used by GpsDrive to save tracks. Like GPSDRIVE a space - seperated format file. See above for a link to GpsDrive. - Contributed by Tobias Minich. - - Geocaching DB - - This is a PDA file format. It was tested against version 2 - of GeocachingDB and a development snapshot of version 3. - Information on the file format came from Dougs Brat and Ron Parker. - A particularly handy way to use GPSBabel on these files is to use - GPSBabel to read a GPX file with Groundspeak (geocaching.com) - extensions and let it write you a GeocachingDB file that contains - the cache names, difficulty, terrain, and such. - - http://vip.hyperusa.com/~dougs/geocachingdb/geocachingdb.htm - - CoPilot - - This code is mostly intended to convert CoPilot Flight Planner - for Palmd/OS atabases into other formats. You probably should - not use this to write CoPilot databases, although the code is - there, because GPSBabel doesn't convert magnetic declination - values. - - Questions, bug reports, etc, to ptomblin at xcski.com - - - http://xcski.com/~ptomblin/CoPilot/ - http://navaid.com/CoPilot/ - - EasyGPS - - This is the binary file format used by EasyGPS. This format is - seemingly being phased out in favor of GPX in newer versions of - EasyGPS, but this allows conversions to and from the old binary - .loc format. - - http://www.easygps.com/ - - Information about and sketchy code to implement this file format - were provided by Eric Cloninger. - - GpilotS - - This is a Palm/OS file format ofr GPilotS. It was tested against - version 6.2. - - http://www.cru.fr/perso/cc/GPilotS/ - - Neither tracks nor routes are supported at this time. - - s_and_t - - This is a format for importing into Microsoft Streets and Trips. - It's been exercised on versions 2003, 2004, and 2005. Detailed - instructions on how to use it, including preserving hyperlinks, - are at - - http://www.gpsbabel.org/formats/s_and_t/Importing_into_Microsoft_Streets_and_Trips_2003.html - - Gcdb - - This is the GeocachingDB by DougsBrat. It works with v2 and v3 - of this program. - - http://vip.hyperusa.com/~dougs/geocachingdb/geocachingdb.htm - - NIMA - - This is a CSV format from the National Imagery and Mapping Agency. - - Fugawi - - This was a requested CSV format, *not* the proprietary binary format - used by Fugawi. Like any other CSV format, GPSBabel cannot read tracks - in this format, but converting a track into it and then importing as - track in Fugawi works. - - It is known to work with Fugawi V3.1.4.635. When importing/exporting - waypoints, one has to specify the order of fields as follows (names of - fields may depend on the language used by Fugawi): - - Name - - Comment - - Description - - Latidude - - Longitude - - Altitude (metres) - - Date (yyyymmdd/yymmdd) - - Time of day (hhmmss) - When importing tracks, use "[ignore]" instead of "Name", "Comment" and - "Description". - - http://www.fugawi.com/ - - custom - - This is a "kitchen sink" CSV format. No known program will - read it, but it's handy for simply converting an arbitrary file - to text so it can be pulled into a spreadsheet or manipulated - with text processing tools. - - tabsep - - Dumps all fields in a traditional Unix tab separated style. - - mapconverter - - Mapconverter is a format this is read by Mapopolis.com's mapconverter - application. Full details of it's usage are available in the file - README.mapconverter. - - navicache - - This is the XML format that's used by Navicache.com for their - geocaching data. There are a number of fields in it that are - marked "required" but are Navicache-specific, so GPSBabel can not - write these files, but we can still read them. - - http://www.navicache.com/cgi-bin/ib312a/ikonboard.cgi?act=ST;f=23;t=334 - - coastexp - - This is the format used by CoastalExplorer (tm). The format is - XML with items uniquely identified by Windows-style UUIDs. - - http://www.rosepointnav.com - - PsiTrex - - This is a text format created by KuDaTa's PsiTrex program for the Psion - PDAs. The format can't be readily handled by XCSV, so this format is - handled explicitly. Waypoints, routes and tracks are all handled, with - icon names used corresponding to verison 1.13 of PsiTrex. - - geoniche - - Geoniche is a Palm/OS application oriented for the off-road user. - This module was contributed by Rick Richardson. - - http://www.nwlink.com/~raydar/GeoNiche/ - - gpl - - This is the 'gpl' format as used in Delorme mapping products. - It is a track format and contains little more than the tracklog - of a GPS that was attached while driving. - - http://www.frontiernet.net/~werner/gps/ - - saroute - - This is a catch-all used by many Delorme mapping products and - reads the anr, rte, and rtd formats as either tracks or routes. - - The 'turns_only' option causes GPSBabel to read only the waypoints - associated with named turns. This should create a list of waypoints - that correspond to the itinerary from Street Atlas. - - The 'turns_important' option only makes sense in conjunction with - the 'simplify' filter. It ensures that the route simplification - process will remove the points corresponding to turns only after - it has removed all other route points. - - Both options only apply to route files from newer versions of - DeLorme software; older versions didn't store the turn information - with the route. - - saplus - - This format is for Street Atlas USA 2004 Plus. - - For geocachers importing data from a tool like GSAK or Spinner, - import the file twice in XData. One will create a file with the - Cache description as a hyperlink on the flag. This can clutter - up the screen and when you try to zoom in, it causes problems. - So the second one will only have a flag. Thus you can turn off - and on which one you want to view. The first time you import - the file, in the assign field types, check the circle above Full - Name and then next. The second time you import the file do not - check any circle and in the second to last column, change URL to - none and then click next. Use the same name you used the first - time but add -Flag to it. - - nmea - - This format is the file representation of the NMEA0183 log and - waypoint format. Representative programs include: - - http://www.genimap.fi/kuluttajatuotteet/alue2.asp?folder=38&subfolder=16662&2057 - - http://homepages.tig.com.au/~robk/datalogger.html - http://www.gpstm.com/eng/features_eng.htm - http://www.gpsmaster.nl/ - http://www.silcom.com/~rwhately/index.html - http://www.visualgps.net/VisualGPSce/default.htm - http://www.gpsu.co.uk/ - http://www.kolumbus.fi/eino.uikkanen/geoconvgb/index.htm - http://www.commlinx.com.au/GPS_recorder.htm - - TEXT - - This is a simple human readable version of the data file, handy for - listings of any type of waypoint files. Use the 'nosep' option - to suppress the lines of dashes between entries. Use the - 'encrypt' option to encrypt hints from Groundspeak GPX files. - Use the 'logs' option to include Groundspeak cache logs. - - The following command line reads a GPX file with Groundspeak extensions - and writes a text file with encrypted hints: - - gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt - - HTML - - HTML output generates a single HTML file of all of the waypoints in - the input file. It supports a number of Geocaching GPX extensions, - as well as filters out potentially harmful HTML from the input file - while maintaining almost all of the source HTML formatting. Use the - 'stylesheet' option to specify a CSS stylesheet to be used with the - resulting HTML file. Use the 'encrypt' option to encrypt hints from - Groundspeak GPX files. Use the 'logs' option to include Groundspeak - cache logs. - - The following command line reads a GPX file with Groundspeak extensions - and writes an HTML file with encrypted hints that is rendered using a - custom stylesheet: - - gpsbabel -i gpx -f 12345.gpx \ - -o html,stylesheet=green.css,encrypt -F 12345.html - - PALMDOC - - PalmDoc output is similar to Text output, except that it generates - a Palm Database (PDB) file suitable for use with programs like - CSpotRun, TealDoc, AportisDoc, Palm Reader, and others. The resulting - file also contains bookmarks to make it easy to jump to a particular - waypoint. To suppress the dashed lines between waypoints, use the - 'nosep' option. To specify a name for the document, use the 'dbname' - option. Use the 'encrypt' option to encrypt hints from Groundspeak - GPX files. Use the 'logs' option to include Groundspeak cache logs. - If you would like the generated bookmarks to start with the short name - for the waypoint, specify the 'bookmarks_short' option. This is - particularly useful when used in combination with the 'sort' filter. - - The following command line reads a GPX file with Groundspeak extensions - and writes a Palm document with encrypted hints and logs: - - gpsbabel -i gpx -f 12345.gpx \ - -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" \ - -F 12345.pdb - - Netstumbler - - NetStumbler 0.4 Summary File -- Another CSV format file. The - default behavior when creating waypoints is to use the SSID for - the short name, and information about the access point for the - description. When the SSID is not unique, is not available, or - consists of whitespace, a shortname is synthesized. The snmac - option uses the MAC address for the shortname, and includes - the unmodified SSID in the description. Different icons are - assigned to encrypted, non-encrypted, stealth, and non-stealth - access points; these may be changed with options. Import only. - - Additional options: - - nseicon - Name of icon used for non-stealth encrypted access points - - nsneicon - Name of icon used for non-stealth non-encrypted access - points - - seicon - Name of icon used for stealth encrypted access points - - sneicon - Name of icon used for stealth non-encrypted access points - - snmac - Always use the MAC address as the shortname. - - IGC - - FAI/IGC Data File -- Used by the international gliding community to - record gliding flights. IGC files can be converted to and from tracks - representing recorded flights, and routes representing task - declarations in other formats. - - BAROIQ - - Serial download protocol for the Brauniger IQ series of barograph - recording flight instruments. Creates a track of altitude vs time - which can be merged with a GPS track of the same flight to create a - three dimensional IGC file. - - hsandv - - HSA Systems Endeavour Navigator format - will import both the old - version 4.x binary files, and the newer XML based ones. - Only writes the new XML (5.0 and above) format. (use the .exp - extension) - - vCARD - - The vCard output is intended to be in a format that enables - waypoints to be viewed with an Apple iPod. This is achieved by - mapping waypoint fields into vCard fields that can be displayed - as 'Contacts' on the iPod. With the iPod mounted as a hard disk - (see your iPod manual for instructions), the resulting VCF - file should be moved into the iPod 'Contacts' folder. As an - alternative, Mac OS X users may prefer to drag the VCF file into - their address book and synchronize with the iPod using iSync. By - default hints are unencrypted; use the 'encrypt' option to - encrypt the hints. - - Hiketech - - This is the .gps format used by the Mac OS X applications - written by HikeTech. These include TopoDraw, Link2GPS, and - GPSWrite. More information about these products can be found at - http://www.hiketech.com - - glogbook - - This is the XML format used by the Garmin Logbook product that - ships with Forerunner and Foretrex. - - http://www.garmin.com - - KML - - We have sketchy support for KML, the Keyhole Markup Language. - There are many features in this file format that we don't yet - support, but simple waypoint lists convert fine. - - GOOGLE - - This format is designed to read the XML emitted when you tack - "&output=js" onto the end of a Google Maps route URL (use the - "link to this page" option to get a usable URL.) This allows - you to plan a route using Google Maps, then download it and use - it in your own mapping program or GPS receiver. If you use a - Unix-compatible operating system, this shell script might be - useful: - - #!/bin/sh - FROM="233 S. Upper Wacker Dr, Chicago, IL" - TO="1060 W. Addison St, Chicago, IL" - wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \ - 2>/dev/null >google_map.js - - gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx - - Note that Internet Explorer has been observed to damage the - XHTML beyond recognition so use a better browser to save the - pages such as Firefox or Mozilla. - - TEF - - TEF, internal called "TourExchangeFormat", is a XML based - export format, used by Map&Guide "Motorrad-Routenplaner 2005/06". - Another posibility to exchange data with this are the .bcr files, - which are sopprted by GPSbabel in both directions (see BCR). - Via XML this software can only export routing data. - So we don't support writing. - - With the option "routevia" you can eliminate calculated route - points from tef source file. - - gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx - - PathAway - - PathAway is a Palm software designed for handling "most" GPS - devices (including BlueTooth). In this time (i mean 2005) a free - tool to convert this database is located on the homepage of - PathAway (www.pathaway.com). But i've read there ... for windows - and the output formats are also very limited. - - AN1 - - This format supports the DeLorme ".an1" drawing file format. It - can currently be used to either read or write drawing files. If - you use this format to create drawing files with routes or waypoints - from another source, it will currently create "Red Flag" symbols - for waypoints, and thick red lines for routes or tracks. It is - possible to merge two drawing layers by doing something like this: - - gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1 - - In this case, the merged data will contain all of the properties - of the original data. - - Currently, GPSBabel only writes drawing layers, as opposed to road, - track, and other specialized layers. If your input file is a road, - track, trail, or waypoint layer, you should not attempt to write to - an .an1 file as the results may be unpredictable. Note that this - also applies to merging files, so you can't currently merge two road - layers with GPSBabel (officially; there is an unsupported "type" - option that works in limited cases.) - - TomTom - - This format can read and write TomTom .ov2 (POI) files, as used by the - TomTom GO and TomTom Navigator. It has been tested with an original - TomTom GO running version 5.00 of the TomTom software. There may be - some records that confuse the input module - if you have an example - of such a record "in the wild", and you aren't restricted from sharing - it, we encourage you to post to the gpsbabel-misc mailing list to - contact a developer. - - Note that in addition to the .ov2 file, you will need a .bmp file for - the icon. It should be 22x22 and 16 colors, and have the same name - (not including the extension) as the .ov2 file. - - VitoSMT - - Vito Navigator II is a Pocket PC GPS application. This format reads - a Vito Navigator II .SMT track file and can work in either waypoint - or track mode. The speed, heading and Dilution of Position data - is written in the notes field. - - Support for writing .SMT tracks is very experimental and may crash - VitoNavigator II on the Pocket PC. - - GDB - - Support for the "Garmin GPS Database" format used by default in - MapSource versions since release 6.0. By default we create gdb's - of version 2. Version 2 is used in Mapsource 6.3 and 6.5. - - Garmin GPS database is an undocumented file format. The - basic info for this module comes from the existing MapSource - conversion code. - - Additional options: - - ver - set the data format version of the output file - (currently 1 or 2); 2 is our default. - via - Drop hidden route points (means calculated stuff) - cat - default category on output (1..16) - - BCR - - This file format (extension .bcr) is used in - "Motorrad Routenplaner 2002-..." by Map&Guide. It is a route-onle - format. If you own a newer release (2005...) you can also use - the XML export and convert via - "gpsbabel ... -i tef ..." to your preferred format. - - May be there are other products from Map&Guide using the format. - - Coordinates are stored in Mercator format. The calculation between - this and our internal format can result in visible differences. - Experience reports are welcome. - - Options: - - index - If more then one route are present in source data, with - this option you can determine, which of this should used - for the output. The range is 1 to number routes in input. - If you don't use this, only the first route will be - converted. - name - Not every input format has a real name for routes in - their data. So you can give the route a nice name. - radius - Overwrites the default value of 6371000.0 meters for - the earth radius. My be this can help to reduce - differences. - - An example with all options: - - gpsbabel -r \ - -i gpx -f in.gpx - -o bcr,index=1,name="From A to B",radius=6371012 \ - -F a_to_b.bcr - - OPENOFFICE - Tab seperated export-all (except geocaching data) file format. - Intended to serve as source for number-processing applications - like OpenOffice, Ploticus and others. Tab was chosen as delimiter - because it is a) supported by both OpenOffice and Ploticus and - b) is not ',', so you can use 'sed -i "s/./,/g" .csv' to adapt it to - locales where ',' is used as decimal seperator. - Contributed by Tobias Minich. - -DATA FILTERS - - GPSBabel supports data filtering. Data filters are invoked from - the command line via the '-x' option. It should be noted that - data filters are invoked in the internal pipeline at the point - that corresponds to their position on the command. This implies - that specifying a filter before reading any data ('-x - -f '), despite being legal, will not have any effect. The - advantage is that filters can be used intermittently between - several variations of input and output functions. It should - also be noted that filtering data from different input types can - sometimes produce undesirable results due to differences in the - native data formats. - - Beware that most filters only apply to a certain kind of - data. This is usually indicated below by referring to points, - tracks or routes in the first sentence which describes each - filter or in the table at http://www.gpsbabel.org/capabilities.html . - - POSITION - - The position filter is designed to remove points based on their - proximity to each other. Distances can be passed on the command - line by passing the distance=XXX option to the filter. Distance - options may be expressed in feet (distance=3f) or meters - (distance=1m). The default is zero feet, essentially a duplicate - position. - - For example: - - gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f \ - -o mapsend -F 3.wpt - - would remove multiple points that are within 1 foot of each other, - leaving just one. - - You can also specify the "all" option, which would remove all - of the points rather than leaving one. - - RADIUS - - The radius filter is designed to include points based on their - proximity to a central point. Distances and the central point - are declared on the command line by passing the distance=X.XX, - lat=X.XX, and lon=X.XX options to the filter. Distance options - may be expressed in miles (distance=3M) or kilometers (distance=3K). - The default is zero miles. Additionally, the exclude option may - be specified to reverse the effect of the filter, so that points - further from the center are kept and closer points are discarded. - - For example: - - gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 \ - -o mapsend -F 2.wpt - - would include only points within 1.5 miles of N30.000 W90.000 - - - DUPLICATE - - The duplicate filter is designed to remove duplicate points based - on their shortname (traditionally a waypoint's name on the GPS - receiver), and/or their location (to a precision of 6 decimals). - This filter supports two options that specify how duplicates will - be recognized, "shortname" and "location". Generally, at least one - of these options is REQUIRED. For example: - - gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname \ - -o gpx -F merged_with_no_dupes.gpx - - would remove points that have duplicate shortnames *AND* duplicate - locations. The result would be a GPX file that more than likely - contains only unique points and point data. - - The duplicate filter can also take an "all" option. If you specify - that option, all instances of a duplicated waypoint will be removed, - not just the second and subsequent instances. If your input file - contains waypoints A, B, B, and C, the output file will contain - waypoints A, B, and C without the "all" option, or just A and C - with the "all" option. This option can be useful as an "ignore - list" in some circumstances. - - Finally, the duplicate filter takes a "correct" option. If you - specify that option, the latitude and longitude frmo later duplicates - will replace the latitude and longitude in earlier waypoints. You - can use this to apply a list of "waypoint corrections" to a larger - file, while keeping all of the other details from the larger file. - - DISTANCE FROM A ROUTE (ARC) - ARC - - The arc filter is designed to include points based on their - proximity to an arc, which is a series of connected line - segments similar to a route or a track but without any - associated data other than the coordinates. - - The arc is defined in a file whose name must be provided with - the file=XXXX option to the filter. That file contains pairs - of coordinates for the vertices of the arc, one coordinate pair - per line. Comments may be included by preceding them with a '#' - character. An arc file looks something like this sample: - - # Lima Road/SR3 north of Fort Wayne, Indiana - 41.150064468 -85.166207433 - 41.150064468 -85.165371895 - 41.149034500 -85.165157318 - 41.147832870 -85.164771080 - 41.146631241 -85.164384842 - 41.144270897 -85.163655281 - 41.141953468 -85.162882805 - - An arc file may optionally contain gaps in the arc. You can - specify such a gap by inserting a line containing "#break" - either on a line by itself or after the coordinates of the - starting point of the new arc segment. - - In addition to the file containing the arc, you should also - specify the maximum distance from the arc that will be accepted; - that distance is declared on the command line with the - distance=X.XX option to the filter. Distance options may be - expressed in miles (distance=3M) or kilometers (distance=3K). - The default is zero miles. You may also specify the exclude option, - which causes GPSBabel to only include points that are further than - the specified distance from the arc. - - For example, assuming the arc above is in a file called "lima_rd.txt": - - gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 \ - -o mapsend -F 2.wpt - - would include only points within one mile of the section of Lima Road - covered by the arc. - - POLYGON - - The polygon filter includes points if they are inside of a polygon. - A polygon file looks like an arc file, except that the arc it - describes must be a closed cycle. That is, for a simple polygon, - the first and last points must be the same. Here's a square: - - # A square (not really) polygon - 41.0000 -85.0000 - 41.0000 -86.0000 - 42.0000 -86.0000 - 42.0000 -85.0000 - 41.0000 -85.0000 - - Polygons may include islands and holes. To specify an island or a - hole, just append it to the main polygon. - - As with the arc filter, you specify a polygon by specifying the name - of the polygon that contains it, using the file option. You can also - specify the exclude option, which reverses the operation of the filter - so that it only includes points that are NOT in the polygon. - - Note that this filter currently will not work properly if your polygon - contains one or both poles or if it spans the line of 180 degrees - east or west longitude. - - For example, assume you have a polygon file that defines the border of - your county, called mycounty.txt. This command line will give you only - the points in your county: - - gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt \ - -o mapsend -F 2.wpt - - SIMPLIFY - - The Simplify filter is used to simplify routes and tracks for use - with formats that limit the number of points they can contain. - The filter takes one required parameter, which is the maximum - number of points a route may contain. It attempts to remove - points from each route until the number of points is at or below - the given maximum, while also attempting to preserve the shape of - the original route as much as possible. - - The quality of the results will vary depending on the density of - points in the original route and the length of the original route. - - For example, suppose you have a route from Street Atlas 2003 that - you wish to use with a Magellan GPS receiver that only supports up - to 50 points in a route: - - gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 \ - -o magellan -F grocery.rte - - REVERSE - - The reverse filter is used to reverse tracks and routes. It's - mostly useful for those few formats where track/route sequence matters - and there isn't a way to reverse them using the program itself. - - The reversal is performed in the laziest way possible. - Timestamps are kept with the original waypoints so the resulting - track or route will have the interesting characteristic that - time runs backwards. This tends to make Magellan Mapsend, - in particular, do a wierd thing and place each waypoint on a - separate day. - - Additionally, if you're using this to reverse a route that - navigates, say, an exit ramp or a one way street, you will be in - for unpleasant ride. application cares about timestamps - - SORT - - This simple filter allows you to alphabetize waypoints by - shortname or by description. It has a special suboption (gcid) - to sort by geocaching.com waypoint ID's when the input comes - from a GPX file that has GC numbers in it. - - STACK - - This filter is designed to solve advanced problems that involve - shuffling multiple lists of waypoints. It has three distinct - sets of suboptions: - - PUSH - - Pushes the current list of waypoints onto the stack. If - the 'copy' suboption is specified, a copy of the current - list is pushed onto the stack; otherwise, the current - list is cleared. - -x stack,push - -x stack,push,copy - - POP - - 'Pops' the top list of waypoints off of the stack. What is - done with that list depends on the suboption specified. If - the 'append' suboption is specified, the top list of waypoints - from the stack is added to the end of the current list of - waypoints. If the 'discard' option is specified, the top - list of waypoints is removed from the stack and discarded, - leaving the current list of waypoints unchanged. If the - 'replace' option is specified, or if no option is specified, - the top list of waypoints from the stack replaces the current - list of waypoints; the previous contents of the current list - are discarded. - -x stack,pop - -x stack,pop,discard - -x stack,pop,append - - SWAP - - Swaps the current list of waypoints with a list from the - stack. If no further options are specified, the current - list is swapped with the top list on the stack. If the - 'depth' option is specified, it indicates which item on - the stack should be swapped. - -x stack,swap - -x stack,swap,depth=2 - - The stack can be used in conjunction with other filters to - implement a "union" or "logical or" functionality. The basic - idea is to use the stack to store copies of the original list - of waypoints, then use the 'swap' function to replace each copy - with a filtered list. Finally, append all of the filtered lists - to create one big list, which is then output. The following - example finds a list of all points that are either inside county A - or inside county B. Any points that are inside both counties are - duplicated (but the duplicates can be removed with the DUPLICATE - filter; see above.) - - gpsbabel -i gpx -f in.gpx \ - -x stack,push,copy \ - -x polygon,file=county_a.txt \ - -x stack,swap \ - -x polygon,file=county_b.txt \ - -x stack,pop,append \ - -o gpx -F out.gpx - - This example reads a large list of waypoints and extracts the - points within 20 miles of each of two cities, writing the - waypoint descriptions into two different PalmDoc files and - exporting all of the points to the GPS receiver: - - gpsbabel -i gpx -f indiana.gpx \ - -x stack,push,copy \ - -x radius,lat=41.0765,lon=-85.1365,distance=20m \ - -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb \ - -x stack,swap \ - -x radius,lat=39.7733,lon=-86.1433,distance=20m \ - -o palmdoc,dbname=Indianapolis -F indianapolis.pdb \ - -x stack,pop,append \ - -o magellan -F fwaind.wpt - - - TRACK - - ( !!! This filter always drops empty tracks !!! ) - - The track filter is a tool for manipulating track lists. - The following options are available: - - TITLE - - Gives the new track(s) a basic title. Basic means if more - than one track is created by filter the title will be - expanded with the date the new track. Special formats (see - UNIX date or strftime for details) are possible. - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,pack,split,title="ACTIVE LOG-%D" \ - -o gpx -F out.gpx PACK - - MOVE - - Change the time of all trackpoints. This is useful if - your track has moved by one or more hours through a - time zone problem. The following example will shift - your track to be one hour later. - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,move=+1h,pack,title="ACTIVE LOG" \ - -o gpx -F out.gpx - - START / STOP - - Filter tracks against time borders. All points outside - this range will be dropped. The date-time paramters - have to be in form of YYYYMMDDHHMMSS; but you may specify - only the most significant portion represented in the the - leftmost fields. See the example, where the time is - specified only through the hour. - - If you only want to get a track mapped on 20 july 2005 from - 10 am to 6pm, you should use this: - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,start=2005072010,stop=2005072018 \ - -o gpx -F out.gpx - - PACK - - With this default option all tracks from input will be - packed into one track. If tracks overlaps in time, the - filter stops working. To pack all the tracks together - into one track and give it a name, use this: - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,pack,title="ACTIVE LOG" \ - -o gpx -F out.gpx - - SPLIT - - The input track will be split into several tracks - depending on date of track points. If there is more - than one track, use the pack option before before - using this. - - To split a single tracks into separate tracks for each day - and name them, use this: - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,split,title="ACTIVE LOG # %Y%m%d" \ - -o gpx -F out.gpx - - If the input has multiple tracks, pack them together before - splitting them back apart per day thusly: - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,pack,split,title="ACTIVE LOG # %D" \ - -o gpx -F out.gpx - - Additionally you can add an interval to the split option. - With this the track will be split if the time between two - points is greater than this parameter. The interval must be - numeric and can be int days, hours, minutes or seconds, - expressed as one of the character "d", "h", "m", or "s". - If no trailing character is present, the units are assumed to - be in seconds. - - For example, to split a track based on an four hour interval, - use this: - - gpsbabel -t \ - -i gpx -f in.gpx \ - -x track,pack,split=4h,title="LOG # %c" \ - -o gpx -F out.gpx - - MERGE - - Merge puts all track points into one single track and - sort them by time. Points with identical time stamp - will be dropped !!! - - If you want to merge tracks from different devices - but from same trip, use this: - - gpsbabel -t \ - -i gpx -f john.gpx \ - -i gpx -f doe.gpx \ - -x track,merge,title="COMBINED LOG" \ - -o gpx -F john_doe.gpx - - DISCARD - - This filter 'fixes' gps data by discarding points with a hdop - and/or vdop over a set limit. If you give both the hdop and a - vdop options, by default points that exceed EITHER are discarded - (OR). This filter processes waypoints, tracks, and routes. - - HDOP (float) - - Points with a hdop exceeding the given value are discarded. - - VDOP (float) - - Points with a vdop exceeding the given value are discarded. - - HDOPANDVDOP - - Only useful if both hdop and vdop are given. Now logical AND - is used, i.e. only points exceeding both given values are - discarded. - - Example: gpsbabel \ - -i gpx -f in.gpx \ - -x discard,hdop=10,vdop=20,hdopandvdop \ - -o gpx -F out.gpx - - Contributed by Tobias Minich. diff --git a/README.contrib b/README.contrib index baa8579ff..b2f618286 100644 --- a/README.contrib +++ b/README.contrib @@ -2,6 +2,9 @@ If you're interested in contributing to this program, here are some guidelines. Mail patches to gpsbabel-code@lists.sourceforge.net for consideration and integration. +Rules to Live By +---------------- + Standards are good. ISO C and POSIX are greatly preferred. Reuse is good, if doing so is not onerous. For example, using the expat @@ -9,6 +12,18 @@ libraries vastly simplifies the XML parsers while increasing their robustness plus those libraries are ubiquitous. So I consider it OK to require expat. +You may find format_skeleton.c and filter_skeleton.c in the source tree +to be helpful examples. Just add meat! + +Compilers complain for a reason. Code shouldn't emit warnings. + +The entire world doesn't run . I've tested this code on +at least five different OSes. If you find yourself wanting to insert +compiler or OS specific magic, please resist. + +Submitting Patches +------------------ + If you are creating a new target you should submit patches (use "cvs diff -uN" to create patches) to the following files: * Yourcode.c and/or Yourcode.h - this is the code required to do your @@ -17,22 +32,59 @@ If you are creating a new target you should submit patches (use GPSBabel. * Makefile - an updated Makefile telling the compiler how to build and link your conversion into GPSBabel -* README - an excerpt for the README about your conversion and any - idiosyncrasies it may have. * testo - an updated script that tests your conversion (this should produce no output if all is good, see the current testo script for examples) * YourOutput - a sample file of code produced by your function (used in testo and lives in a directory called "reference"). +* Documentation - see below. Please ensure that you are building and testing against the latest code from the top of the CVS tree and that any code you modify is the latest version from the CVS - Note: code changes sometimes occur frequently! -Compilers complain for a reason. Code shouldn't emit warnings. +Documentation +------------- + +HTML and text documentation are generated automatically from DocBook +source located in the "xmldoc" directory. That directory contains +two subdirectories of interest: "formats" and "filters". If your +contribution adds or affects a format, you'll want to be in the "formats" +directory. Otherwise, you'll want to be in the "filters" directory. + +You should contribute a file called "yourname.xml", where "yourname" is the +name you would give on the command-line to invoke your new format or filter. +For example, the arc filter is documented in "filters/arc.xml". + +This file contains a general description of your format or filter, any +limitations in your support for it, and anything else the end user should +know. For file formats, links to manufacturers' websites are encouraged. +The contents of this file are not valid or even well-formed XML on their own; +they are included into a larger framework. If you know DocBook, you should +ensure that the contents of this file will validate if included in a
. +If you do not know DocBook, see the other files in this directory for examples +or see http://docbook.org/tdg/en/html/docbook.html for the gory details. Tags +of interest will almost certainly include for paragraphs, + for web links, and for +example command lines. + +For each option supported by your format or filter, you should also contribute +a file in the "options" subdirectory called "yourname-youroption.xml", again +using the names you would use on the command line to invoke your format or +filter with that particular option. For example, the "distance" option to the +"arc" filter is documented in "filters/options/arc-distance.xml". These +files are similar to the general description above, and should meet the same +validation requirements. + +As of this writing, there are two formats that violate this rule: Magellan +serial and Microsoft Streets & Trips. Because those formats have the same +names as other formats, their descriptions are located in "magellan1.xml" and +"msroute1.xml" respectively. These are special cases, and you should do your +best to ensure that they remain the only special cases. + +Note that the automated framework already includes the name and description of +your format and its options as described in vecs.c and yourcode.c, so there is +no need to repeat that information in your documentation. -The entire world doesn't run . I've tested this code on -at least five different OSes. If you find yourself wanting to insert -compiler or OS specific magic, please resist. Enjoy! diff --git a/an1.c b/an1.c index 0b72ce59c..c6483eb61 100644 --- a/an1.c +++ b/an1.c @@ -22,24 +22,60 @@ #include #include #include +#include #define MYNAME "an1" #include "defs.h" -FILE *infile; -FILE *outfile; +static FILE *infile; +static FILE *outfile; static char *output_type = NULL; -long output_type_num = 0; +static char *road_changes = NULL; +static char *nogc = NULL; +static char *opt_symbol = NULL; +static char *opt_color = NULL; +static char *opt_zoom = NULL; +static char *opt_wpt_type = NULL; +static char *opt_radius = NULL; + +static short output_type_num = 0; +static short opt_zoom_num = 0; +static long opt_color_num = 0; +static short wpt_type_num = 0; +static short last_read_type = 0; +static double radius = 0.0; static long serial=10000; static long rtserial=1; +typedef struct roadchange { + long type; + char *name; +} roadchange; + +roadchange *roadchanges = NULL; + static arglist_t an1_args[] = { - {"type", &output_type, "Type of .an1 file (0=drawing)", - "0", ARGTYPE_HIDDEN | ARGTYPE_INT }, - {0, 0, 0, 0 } + {"type", &output_type, "Type of .an1 file", + "", ARGTYPE_STRING, ARG_NOMINMAX }, + {"road", &road_changes, "Road type changes", + "", ARGTYPE_STRING, ARG_NOMINMAX }, + {"nogc", &nogc, "Do not add geocache data to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"deficon", &opt_symbol, "Symbol to use for point data", + "Red Flag", ARGTYPE_STRING, ARG_NOMINMAX }, + {"color", &opt_color, "Color for lines or mapnotes", + "red", ARGTYPE_STRING, ARG_NOMINMAX }, + {"zoom", &opt_zoom, "Zoom level to reduce points", + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"wpt_type", &opt_wpt_type, + "Waypoint type", + "", ARGTYPE_STRING, ARG_NOMINMAX }, + {"radius", &opt_radius, "Radius for circles", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; typedef struct guid { @@ -91,7 +127,7 @@ ReadDouble( FILE * f ) double tmp = 0; double result = 0; fread(&tmp, sizeof(tmp),1,f); - le_read64(&result, &tmp ); + result = le_read_double( &tmp ); return result; } @@ -99,7 +135,7 @@ static void WriteDouble(FILE * f, double d) { double tmp = 0; - le_read64( &tmp, (void *)&d ); + le_write_double( &tmp, d ); fwrite( &tmp, sizeof(tmp), 1, f ); } @@ -118,7 +154,9 @@ static unsigned char ReadChar( FILE *f ) { unsigned char result = 0; - fread( &result, 1, 1, f ); + if (fread( &result, 1, 1, f ) < 1) { + fatal( MYNAME ": error reading an1 file. Perhaps this isn't really an an1 file."); + } return result; } @@ -170,20 +208,13 @@ Skip(FILE * f, static double DecodeOrd( long ord ) { - return (double)(0x80000000-ord)/(0x800000); + return (double)((gbint32)(0x80000000 - ord)) / 0x800000; } static long EncodeOrd( double ord ) { - unsigned long tmp = ord * 0x800000; - return 0x80000000UL-tmp; -} - -static int -IsGuidEqual( GUID *a, GUID *b ) -{ - return !memcmp( a, b, sizeof( GUID )); + return (gbint32)(0x80000000 - (gbint32)(ord * 0x800000)); } typedef struct { @@ -210,7 +241,7 @@ typedef struct { unsigned char create_zoom; unsigned char visible_zoom; short unk5; - double radius; + double radius; /* in km */ char *name; char *fontname; GUID guid; @@ -223,6 +254,14 @@ typedef struct { long fillcolor; long unk6; long fillflags; + + /* Added in SA2006/Topo 6.0 */ + short unk6_1; + char *url; + char *comment; + long creation_time; + long modification_time; + char *image_name; } an1_waypoint_record; typedef struct { @@ -236,8 +275,7 @@ typedef struct { typedef struct { format_specific_data fs; - short magic; - short unk1; + long roadtype; short serial; long unk2; short unk3; @@ -258,9 +296,13 @@ typedef struct { static an1_waypoint_record *Alloc_AN1_Waypoint( ); void Destroy_AN1_Waypoint( void *vwpt ) { + an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; xfree( wpt->name ); xfree( wpt->fontname ); + if ( wpt->url ) xfree( wpt->url ); + if ( wpt->comment ) xfree( wpt->comment ); + if ( wpt->image_name ) xfree( wpt->image_name ); xfree( vwpt ); } @@ -270,6 +312,9 @@ void Copy_AN1_Waypoint( void **vdwpt, void *vwpt ) { memcpy( dwpt, wpt, sizeof( an1_waypoint_record )); dwpt->name = xstrdup( wpt->name ); dwpt->fontname = xstrdup( wpt->fontname ); + dwpt->url = xstrdup( wpt->url ); + dwpt->comment = xstrdup( wpt->comment ); + dwpt->image_name = xstrdup( wpt->image_name ); *vdwpt = (void *)dwpt; } @@ -279,6 +324,7 @@ static an1_waypoint_record *Alloc_AN1_Waypoint( ) { result->fs.type = FS_AN1W; result->fs.copy = Copy_AN1_Waypoint; result->fs.destroy = Destroy_AN1_Waypoint; + result->fs.convert = NULL; return result; } @@ -301,6 +347,7 @@ static an1_vertex_record *Alloc_AN1_Vertex() { result->fs.type = FS_AN1V; result->fs.copy = Copy_AN1_Vertex; result->fs.destroy = Destroy_AN1_Vertex; + result->fs.convert = NULL; return result; } @@ -327,6 +374,7 @@ static an1_line_record *Alloc_AN1_Line( ) { result->fs.type = FS_AN1L; result->fs.copy = Copy_AN1_Line; result->fs.destroy = Destroy_AN1_Line; + result->fs.convert = NULL; return result; } @@ -355,8 +403,64 @@ static void Read_AN1_Waypoint( FILE *f, an1_waypoint_record *wpt ) { wpt->radius = ReadDouble( f ); len = ReadShort( f ); wpt->name = ReadString( f, len ); - len = ReadShort( f ); - wpt->fontname = ReadString( f, len ); + + if ( len != strlen(wpt->name)) { + /* This happens in 06/6.0 files that put extra data in the + * name record for backward compatibility's sake */ + char *ofs = wpt->name + strlen( wpt->name ) + 1; + wpt->unk6_1 = le_read16( ofs ); + ofs += 2; + + len = le_read16( ofs ); + ofs += 2; + + if ( len ) { + char *oldurlstr; + /* + * Trust URL encoded in new format over one in + * old format if both are present. Whack the + * name starting at '{URL='. + */ + oldurlstr = strstr(wpt->name, "{URL="); + if (oldurlstr) { + *oldurlstr = 0; + } + + wpt->url = xcalloc( len+1, 1 ); + memcpy( wpt->url, ofs, len ); + ofs += len; + } + + len = le_read16( ofs ); + ofs += 2; + + if ( len ) { + wpt->comment = xcalloc( len+1, 1 ); + memcpy( wpt->comment, ofs, len ); + ofs += len; + } + + /* these are quadwords, presumably for year-2038 compat. */ + wpt->creation_time = le_read32( ofs ); + ofs += 8; + + wpt->modification_time = le_read32( ofs ); + ofs += 8; + } + + if ( wpt->type == 0x12 ) { + /* 'image' type */ + ReadShort( f ); /* length of font + filename */ + len = ReadShort( f ); + wpt->fontname = ReadString( f, len ); + len = ReadShort( f ); + wpt->image_name = ReadString( f, len ); + } + else { + len = ReadShort( f ); + wpt->fontname = ReadString( f, len ); + wpt->image_name = NULL; + } ReadGuid( f, &wpt->guid ); wpt->fontcolor = ReadLong( f ); wpt->fontstyle = ReadLong( f ); @@ -387,12 +491,64 @@ static void Write_AN1_Waypoint( FILE *f, an1_waypoint_record *wpt ) { WriteChar( f, wpt->visible_zoom ); WriteShort( f, wpt->unk5 ); WriteDouble( f, wpt->radius ); - len = strlen( wpt->name ); + + len = strlen( wpt->name ) + 1 + 2 + 2 + + (wpt->url ? strlen( wpt->url ) : 0) + 2 + + (wpt->comment ? strlen( wpt->comment ) : 0) + 8 + 8; WriteShort( f, len ); WriteString( f, wpt->name ); - len = strlen( wpt->fontname ); - WriteShort( f, len ); - WriteString( f, wpt->fontname ); + WriteChar( f, 0 ); /* name string terminator */ + + WriteShort( f, wpt->unk6_1 ); + + if ( wpt->url ) { + WriteShort( f, strlen(wpt->url)); + WriteString( f, wpt->url ); + } + else { + WriteShort( f, 0 ); + } + + if ( wpt->comment ) { + WriteShort( f, strlen(wpt->comment)); + WriteString( f, wpt->comment ); + } + else { + WriteShort( f, 0 ); + } + + WriteLong( f, wpt->creation_time ); + WriteLong( f, 0 ); + + WriteLong( f, wpt->modification_time ); + WriteLong( f, 0 ); + + if ( wpt->type == 0x12 ) { /* image */ + len = 2 + (wpt->fontname ? strlen( wpt->fontname ) : 0 ) + + 2 + (wpt->image_name ? strlen( wpt->image_name ) : 0 ); + WriteShort( f, len ); + if ( wpt->fontname ) { + len = strlen( wpt->fontname ); + WriteShort( f, len ); + WriteString( f, wpt->fontname ); + } + else { + WriteShort( f, 0 ); + } + if ( wpt->image_name ) { + len = strlen( wpt->image_name ); + WriteShort( f, len ); + WriteString( f, wpt->image_name ); + } + else { + WriteShort( f, 0 ); + } + } + else { + len = strlen( wpt->fontname ); + WriteShort( f, len ); + WriteString( f, wpt->fontname ); + } WriteGuid( f, &wpt->guid ); WriteLong( f, wpt->fontcolor ); WriteLong( f, wpt->fontstyle ); @@ -426,8 +582,7 @@ static void Read_AN1_Line( FILE *f, an1_line_record *line ) { short len; - line->magic = ReadShort( f ); - line->unk1 = ReadShort( f ); + line->roadtype = ReadLong( f ); line->serial = ReadShort( f ); line->unk2 = ReadLong( f ); line->unk3 = ReadShort( f ); @@ -449,8 +604,7 @@ static void Read_AN1_Line( FILE *f, an1_line_record *line ) { static void Write_AN1_Line( FILE *f, an1_line_record *line ) { short len; - WriteShort( f, line->magic ); - WriteShort( f, line->unk1 ); + WriteLong( f, line->roadtype ); WriteShort( f, line->serial ); WriteLong( f, line->unk2 ); WriteShort( f, line->unk3 ); @@ -511,11 +665,13 @@ static void Read_AN1_Header( FILE *f ) { magic = ReadShort( f ); type = ReadShort( f ); + + last_read_type = type; } static void Write_AN1_Header( FILE *f ) { WriteShort( f, 11557 ); - WriteShort( f, (short) atoi( output_type ) ); + WriteShort( f, output_type_num ); } static void Read_AN1_Bitmaps( FILE *f ) { @@ -557,6 +713,7 @@ static void Read_AN1_Waypoints( FILE *f ) { an1_waypoint_record *rec = NULL; waypoint *wpt_tmp; char *icon = NULL; + char *url = NULL; ReadShort( f ); count = ReadLong( f ); for (i = 0; i < count; i++ ) { @@ -564,11 +721,27 @@ static void Read_AN1_Waypoints( FILE *f ) { Read_AN1_Waypoint( f, rec ); wpt_tmp = waypt_new(); + if ( rec->creation_time ) { + wpt_tmp->creation_time = rec->creation_time; + } wpt_tmp->longitude = -DecodeOrd( rec->lon ); wpt_tmp->latitude = DecodeOrd( rec->lat ); + wpt_tmp->notes = xstrdup( rec->comment ); wpt_tmp->description = xstrdup( rec->name ); + if ( rec->url ) { + wpt_tmp->url = xstrdup( rec->url ); + } + else if ( NULL != (url=strstr(wpt_tmp->description, "{URL="))) { + *url = '\0'; + url += 5; + url[strlen(url)-1] = '\0'; + wpt_tmp->url = xstrdup( url ); + } - if (FindIconByGuid(&rec->guid, &icon)) { + if ( rec->image_name ) { + wpt_tmp->icon_descr = xstrdup( rec->image_name ); + } + else if (FindIconByGuid(&rec->guid, &icon)) { wpt_tmp->icon_descr = icon; } @@ -586,29 +759,74 @@ Write_One_AN1_Waypoint( const waypoint *wpt ) format_specific_data *fs = NULL; fs = fs_chain_find( wpt->fs, FS_AN1W ); - if ( fs ) { rec = (an1_waypoint_record *)fs; xfree( rec->name ); local = 0; + if ( opt_zoom ) + rec->visible_zoom = opt_zoom_num; } else { rec = Alloc_AN1_Waypoint(); local = 1; rec->magic = 1; - rec->type = 1; + rec->type = wpt_type_num; rec->unk2 = 3; rec->unk3 = 18561; + rec->radius = radius; + rec->fillcolor = opt_color_num; + rec->fillflags = 3; + if ( wpt_type_num == 5 ) rec->fillflags = 0x8200; + rec->height = -50; + rec->width = 20; rec->fontname = xstrdup( "Arial" ); - FindIconByName( "Red Flag", &rec->guid ); + FindIconByName( opt_symbol, &rec->guid ); rec->fontsize = 10; + rec->visible_zoom = opt_zoom?opt_zoom_num:10; + rec->unk6_1 = 1; } rec->name = xstrdup( wpt->description ); + + if ( !nogc && wpt->gc_data.id ) { + char *extra = xmalloc( 25 + strlen(wpt->gc_data.placer) + strlen( wpt->shortname )); + sprintf( extra, "\r\nBy %s\r\n%s (%1.1f/%1.1f)", + wpt->gc_data.placer, + wpt->shortname, wpt->gc_data.diff/10.0, + wpt->gc_data.terr/10.0); + rec->name = xstrappend( rec->name, extra ); + xfree( extra ); + } + + if ( wpt->url ) { + int len = 7+strlen(wpt->url); + char *extra = (char *)xmalloc( len ); + sprintf( extra, "{URL=%s}", wpt->url ); + rec->name = xstrappend( rec->name, extra ); + xfree( extra ); + rec->url = xstrdup( wpt->url ); + } + + if ( wpt->notes ) { + if ( rec->comment ) { + xfree( rec->comment ); + } + rec->comment = xstrdup( wpt->notes ); + } + + + rec->creation_time = rec->modification_time = wpt->creation_time; rec->lat = EncodeOrd( wpt->latitude ); rec->lon = EncodeOrd( -wpt->longitude ); rec->serial = serial++; - if ( wpt->icon_descr ) { + if ( rec->type == 0x12 ) { /* image */ + if ( strstr( wpt->icon_descr, ":\\" )) { + rec->image_name = xstrdup( wpt->icon_descr ); + rec->height = -244; + rec->width = -1; + } + } + if ( !rec->image_name && wpt->icon_descr ) { FindIconByName( (char *)(void *)wpt->icon_descr, &rec->guid ); } @@ -651,7 +869,7 @@ static void Read_AN1_Lines( FILE *f ) { wpt_tmp->latitude = DecodeOrd( vert->lat ); wpt_tmp->longitude = -DecodeOrd( vert->lon ); wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5x", rtserial++ ); + sprintf( wpt_tmp->shortname, "\\%5.5lx", rtserial++ ); fs_chain_add( &wpt_tmp->fs, (format_specific_data *)vert ); route_add_wpt(rte_head, wpt_tmp); @@ -659,6 +877,27 @@ static void Read_AN1_Lines( FILE *f ) { } } +static void +Make_Road_Changes( an1_line_record *rec ) { + int i = 0; + + if ( !rec ) { + return; + } + + if ( !roadchanges ) { + return; + } + + while ( roadchanges[i].name ) { + if ( !case_ignore_strcmp(roadchanges[i].name, rec->name )) { + rec->roadtype = roadchanges[i].type; + break; + } + i++; + } +} + static void Write_One_AN1_Line( const route_head *rte ) { @@ -677,12 +916,12 @@ Write_One_AN1_Line( const route_head *rte ) rec = Alloc_AN1_Line(); memcpy( rec, fs, sizeof(an1_line_record)); local = 1; - rec->magic = 4112; - rec->unk1 = 4359; + rec->roadtype = 0x11100541; rec->unk2 = 655360; rec->type = 14; rec->unk8 = 2; } // end if + Make_Road_Changes( rec ); break; case 2: if ( rec->type != 15 ) { @@ -705,27 +944,26 @@ Write_One_AN1_Line( const route_head *rte ) else { rec = Alloc_AN1_Line(); local = 1; + rec->name = NULL; switch (output_type_num) { /* drawing road trail waypoint track */ case 1: /* road */ - rec->magic = 4112; - rec->unk1 = 4359; + rec->roadtype = 0x11100541; rec->unk2 = 655360; rec->type = 14; rec->unk8 = 2; + rec->name = xstrdup( rte->rte_name ); break; case 2: /* trail */ - rec->magic = 7248; - rec->unk1 = 4359; + rec->roadtype = 0x11071c50; rec->unk2 = 917504; rec->type = 15; rec->unk8 = 2; break; case 4: /* track */ - rec->magic = 21; - rec->unk1 = 18560; + rec->roadtype = 0x48800015; rec->unk2 = 917504; rec->type = 16; rec->unk4 = 2; @@ -735,18 +973,19 @@ Write_One_AN1_Line( const route_head *rte ) case 0: /* drawing */ case 3: /* waypoint - shouldn't have lines */ default: - rec->magic = 21; - rec->unk1 = 18560; + rec->roadtype = 0x48800015; rec->unk2 = 1048576; rec->type = 2; rec->unk4 = 2; rec->lineweight = 6; - rec->linecolor = 255; /* red */ + rec->linecolor = opt_color_num; /* red */ rec->unk5 = 3; rec->unk8 = 2; break; } - rec->name = xstrdup( "" ); + if ( !rec->name ) { + rec->name = xstrdup( "" ); + } } rec->serial = serial++; @@ -792,11 +1031,186 @@ static void Write_AN1_Lines( FILE *f ) { track_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); } +static void +Init_Wpt_Type( void ) +{ + if ( !opt_wpt_type || !opt_wpt_type[0] ) { + wpt_type_num = 1; /* marker */ + return; + } + if ((opt_wpt_type[0] & 0xf0) == 0x30) { + wpt_type_num = atoi( opt_wpt_type ); + } + else { + wpt_type_num = 1; /* marker */ + if ( !case_ignore_strcmp( opt_wpt_type, "marker" )) { + wpt_type_num = 1; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "symbol" )) { + wpt_type_num = 1; /* symbol and marker are synonyms */ + } + else if ( !case_ignore_strcmp( opt_wpt_type, "text" )) { + wpt_type_num = 4; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "mapnote" )) { + wpt_type_num = 6; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "circle" )) { + wpt_type_num = 5; + } + else if ( !case_ignore_strcmp( opt_wpt_type, "image" )) { + wpt_type_num = 18; + } + else { + fatal( MYNAME ": wpt_type must be " + "symbol, text, mapnote, circle, or image\n" ); + } + } +} + +static void +Init_Output_Type( void ) +{ + if ( !output_type || !output_type[0]) { + output_type_num = last_read_type; + return; + } + if ( (output_type[0] & 0xf0 ) == 0x30) { + output_type_num = atoi( output_type ); + } + else { + output_type_num = 0; + if ( !case_ignore_strcmp(output_type, "drawing")) { + output_type_num = 0; + } + else if ( !case_ignore_strcmp(output_type, "road")) { + output_type_num = 1; + } + else if ( !case_ignore_strcmp(output_type, "trail")) { + output_type_num = 2; + } + else if ( !case_ignore_strcmp(output_type, "waypoint")) { + output_type_num = 3; + } + else if ( !case_ignore_strcmp(output_type, "track")) { + output_type_num = 4; + } + else { + fatal(MYNAME ": type must be " + "drawing, road, trail, waypoint, or track\n"); + } + } + last_read_type = output_type_num; +} + +static long +Parse_Change_Type( char *type ) { + long retval = 0x11100541; + + if ( !case_ignore_strcmp( type, "limited" )) { + retval = 0x11070430; + } + else if ( !case_ignore_strcmp( type, "toll" )) { + retval = 0x11070470; + } + else if ( !case_ignore_strcmp( type, "us" )) { + retval = 0x11070870; + } + else if ( !case_ignore_strcmp( type, "state" )) { + retval = 0x11070c10; + } + else if ( !case_ignore_strcmp( type, "primary" )) { + /* primary state/provincial routes */ + retval = 0x11070840; + } + else if ( !case_ignore_strcmp( type, "major" )) { + retval = 0x11070c30; + } + else if ( !case_ignore_strcmp( type, "local" )) { + retval = 0x11071010; + } + else if ( !case_ignore_strcmp( type, "ramp" )) { + retval = 0x11070cb0; + } + else if ( !case_ignore_strcmp( type, "ferry" )) { + retval = 0x11070ca0; + } + else if ( !case_ignore_strcmp( type, "editable" )) { + retval = 0x11100541; + } + else { + fatal( MYNAME ": unknown road type for road changes\n" ); + } + return retval; +} + +static void +Free_Road_Changes( void ) +{ + int i = 0; + if ( roadchanges ) { + while ( roadchanges[i].name ) { + xfree(roadchanges[i].name ); + i++; + } + xfree( roadchanges ); + } + roadchanges = NULL; +} + +static void +Init_Road_Changes( void ) +{ + int count = 0; + char *strType = NULL; + char *name = NULL; + char *bar = NULL; + char *copy = NULL; + Free_Road_Changes(); + + if ( !road_changes || !road_changes[0] ) { + return; + } + bar = strchr( road_changes, '!' ); + while ( bar ) { + count++; + bar = strchr( bar+1, '!' ); + } + if ( !(count&1)) { + fatal( MYNAME ": invalid format for road changes\n" ); + } + count = 1 + count / 2; + roadchanges = (roadchange *)xmalloc( (count+1) * sizeof(roadchange)); + + roadchanges[count].type = 0; + roadchanges[count].name = NULL; + + copy = xstrdup( road_changes ); + bar = copy; + + while ( count ) { + count--; + name = bar; + bar = strchr( name, '!' ); + *bar = '\0'; + bar++; + strType = bar; + bar = strchr( strType, '!' ); + if ( bar ) { + *bar = '\0'; + bar++; + } + roadchanges[count].name = xstrdup( name ); + roadchanges[count].type = Parse_Change_Type( strType ); + } + + xfree( copy ); +} + static void rd_init(const char *fname) { infile = xfopen(fname, "rb", MYNAME); - output_type_num = atoi( output_type ); } static void @@ -818,12 +1232,26 @@ static void wr_init(const char *fname) { outfile = xfopen( fname, "wb", MYNAME ); - output_type_num = atoi( output_type ); + Init_Output_Type(); + Init_Road_Changes(); + opt_color_num = color_to_bbggrr(opt_color); + Init_Wpt_Type(); + if ( opt_zoom ) { + opt_zoom_num = atoi(opt_zoom); + } + radius = .1609344; /* 1/10 mi */ + if ( opt_radius ) { + radius = atof(opt_radius); + if ( !strchr(opt_radius,'k') && !strchr(opt_radius,'K')) { + radius *= 5280*12*2.54/100000; + } + } } static void wr_deinit( void ) { + Free_Road_Changes(); fclose(outfile); } @@ -846,5 +1274,6 @@ ff_vecs_t an1_vecs = { my_read, my_write, NULL, - an1_args + an1_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/an1sym.h b/an1sym.h index 8c5f0b41d..bf25c9303 100644 --- a/an1sym.h +++ b/an1sym.h @@ -371,7 +371,7 @@ struct defguid { {{0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}}, "Transportation"}, {{0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}}, - "Fishing"}, + "Fishing 2"}, {{0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}}, "Automotive"}, {{0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}}, @@ -381,7 +381,7 @@ struct defguid { {{0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}}, "Mostly Cloudy"}, {{0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}}, - "Tornado"}, + "Hurricane"}, {{0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}}, "Lightning"}, {{0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}}, diff --git a/arcdist.c b/arcdist.c index 800c45dd4..ecbc75db2 100644 --- a/arcdist.c +++ b/arcdist.c @@ -18,14 +18,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -#include #include "defs.h" +#include "filterdefs.h" #include "grtcirc.h" +#if FILTERS_ENABLED #define MYNAME "Arc filter" -extern queue waypt_head; - static double pos_dist; static char *distopt = NULL; static char *arcfileopt = NULL; @@ -39,14 +38,14 @@ typedef struct { static arglist_t arcdist_args[] = { {"file", &arcfileopt, "File containing vertices of arc", - NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED}, + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX}, {"distance", &distopt, "Maximum distance from arc", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED}, + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX}, {"exclude", &exclopt, "Exclude points close to the arc", NULL, - ARGTYPE_BOOL}, + ARGTYPE_BOOL, ARG_NOMINMAX}, {"points", &ptsopt, "Use distance from vertices not lines", - NULL, ARGTYPE_BOOL}, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR }; #define BADVAL 999999 @@ -60,17 +59,16 @@ arcdist_process(void) extra_data *ed; double lat1, lon1, lat2, lon2; int fileline = 0; + char *line; + gbfile *file_in; - FILE *arcfile = xfopen( arcfileopt, "r", MYNAME ); + file_in = gbfopen(arcfileopt, "r", MYNAME); lat1 = lon1 = lat2 = lon2 = BADVAL; - while ( !feof(arcfile)) { - char line[200]; + while ((line = gbfgetstr(file_in))) { char *pound = NULL; int argsfound = 0; - fgets( line, sizeof(line), arcfile ); - fileline++; pound = strchr( line, '#' ); @@ -92,20 +90,6 @@ arcdist_process(void) QUEUE_FOR_EACH(&waypt_head, elem, tmp) { waypointp = (waypoint *)elem; - if ( ptsopt ) { - dist = gcdist( lat2*M_PI/180.0, lon2*M_PI/180.0, - waypointp->latitude*M_PI/180.0, - waypointp->longitude*M_PI/180.0 ); - } - else { - dist = linedist(lat1, lon1, lat2, lon2, - waypointp->latitude, - waypointp->longitude ); - } - - /* convert radians to float point statute miles */ - dist = tomiles(dist); - if ( waypointp->extra_data ) { ed = (extra_data *) waypointp->extra_data; } @@ -113,18 +97,33 @@ arcdist_process(void) ed = (extra_data *) xcalloc(1, sizeof(*ed)); ed->distance = BADVAL; } - if ( ed->distance > dist ) { + if ( ed->distance == BADVAL || ed->distance >= pos_dist ) { + if ( ptsopt ) { + dist = gcdist( RAD(lat2), RAD(lon2), + RAD(waypointp->latitude), + RAD(waypointp->longitude) ); + } + else { + dist = linedist(lat1, lon1, lat2, lon2, + waypointp->latitude, + waypointp->longitude ); + } + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if ( ed->distance > dist ) { ed->distance = dist; + } + waypointp->extra_data = ed; } - waypointp->extra_data = ed; } } lat1 = lat2; lon1 = lon2; } - fclose(arcfile); - + gbfclose(file_in); QUEUE_FOR_EACH(&waypt_head, elem, tmp) { waypoint *wp = (waypoint *) elem; @@ -168,3 +167,4 @@ filter_vecs_t arcdist_vecs = { NULL, arcdist_args }; +#endif // FILTERS_ENABLED diff --git a/axim_gpb.c b/axim_gpb.c new file mode 100644 index 000000000..398fe3788 --- /dev/null +++ b/axim_gpb.c @@ -0,0 +1,182 @@ +/* + + Track reader for "Dell Axim Navigation System" GPB files, + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include +#include +#include + +#define MYNAME "axim_gpb" + +#define RECORD_LEN 344 + +static FILE *fin; + +static +arglist_t axim_gpb_args[] = { + ARG_TERMINATOR +}; + +static float +le_read32_float(const void *src) +{ + float f; + gbint32 i; + + i = le_read32(src); + memcpy(&f, &i, 4); + + return f; +} + +static void +decode_buff(const char *buff, route_head *track) +{ + struct tm tm; + double lat, lon, alt, dir; + float vdop, hdop, pdop, spd, Uf1; + int sats; + waypoint *wpt; + + wpt = waypt_new(); + + memset(&tm, '\0', sizeof(tm)); + + tm.tm_year = le_read16((void *) (buff + 16)); + tm.tm_mon = le_read16((void *) (buff + 18)); + tm.tm_mday = le_read16((void *) (buff + 22)); + tm.tm_hour = le_read16((void *) (buff + 24)); + tm.tm_min = le_read16((void *) (buff + 26)); + tm.tm_sec = le_read16((void *) (buff + 28)); + lat = le_read_double( (void *) (buff + 32)); + lon = le_read_double( (void *) (buff + 40)); + spd = le_read32_float((void *) (buff + 48)); + dir = le_read32_float((void *) (buff + 52)); + + alt = le_read32_float((void *) (buff + 64)); + Uf1 = le_read32_float((void *) (buff + 68)); + + hdop = le_read32_float((void *) (buff + 84)); + vdop = le_read32_float((void *) (buff + 88)); + pdop = le_read32_float((void *) (buff + 92)); + sats = le_read16((void *) (buff + 96)); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; +#if 0 + /* These values can be, but must not be right. */ + /* Further checks are needed to verify that. */ + /* (!!! reference data !!!) */ + wpt->course = dir; + wpt->hdop = hdop; + wpt->vdop = vdop; + wpt->pdop = pdop; + wpt->sat = sats; + wpt->speed = spd * 10; +#endif + /* We don't have a header with some magic fixed numbers or strings. */ + /* So let us check the range for some basic values */ + + is_fatal( + (tm.tm_year < 2005) || + (tm.tm_mon < 1) || (tm.tm_mon > 12) || + (tm.tm_mday < 1) || (tm.tm_mday > 31) || + (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60), + MYNAME ": Invalid or unsupported file (invalid time-stamp)."); + is_fatal( + (fabs(wpt->latitude) > 180) || + (fabs(wpt->longitude) > 90), + MYNAME ": Invalid or unsupported file (lat or/and lon out of range)."); + + /* post work */ + + tm.tm_year-=1900; + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + + track_add_wpt(track, wpt); +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +axim_gpb_rd_init(const char *fname) +{ + fin = xfopen(fname, "rb", MYNAME); +} + +static void +axim_gpb_rd_deinit(void) +{ + fclose(fin); +} + +static void +axim_gpb_read(void) +{ + char buff[RECORD_LEN]; + route_head *track = NULL; + size_t bytes; + long filesize, left; + + fseek(fin, 0, SEEK_END); + filesize = ftell(fin); + + left = filesize - ((filesize / RECORD_LEN) * RECORD_LEN); + is_fatal((left != 0), MYNAME ": Invalid or unsupported file (filesize)."); + + fseek(fin, 0, SEEK_SET); /* seek file to start */ + + while ((bytes = fread(buff, 1, RECORD_LEN, fin))) + { + if (track == NULL) + { + track = route_head_alloc(); + track_add_head(track); + } + decode_buff(buff, track); + } +} + +/**************************************************************************/ + +ff_vecs_t axim_gpb_vecs = { + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */, + }, + axim_gpb_rd_init, + NULL, + axim_gpb_rd_deinit, + NULL, + axim_gpb_read, + NULL, + NULL, + axim_gpb_args, + CET_CHARSET_ASCII, 0 +}; +/**************************************************************************/ diff --git a/bcr.c b/bcr.c index 29bde2fa7..657d21733 100644 --- a/bcr.c +++ b/bcr.c @@ -2,7 +2,7 @@ Support for Motorrad Routenplaner (Map&Guide) .bcr files. - Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de + Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,6 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ +/* + 2006/01/22: reader simplified with inifile library +*/ #include "defs.h" #include "garmin_tables.h" @@ -26,19 +29,13 @@ #include #include #include - +#include "cet_util.h" +#include "inifile.h" #define MYNAME "bcr" -#define BCR_DEBUG -// #undef BCR_DEBUG +#undef BCR_DEBUG -#define SEC_UNKNOWN 0 -#define SEC_CLIENT 1 -#define SEC_ROUTE 2 -#define SEC_DESCR 3 -#define SEC_COORD 4 - #define R_EARTH 6371000 /* radius of our big blue ball */ /* @@ -46,10 +43,11 @@ but this seems to be used by Map&Guide when exporting to XML. */ -static FILE *fin, *fout; -char *filename; -int curr_rte_num, target_rte_num; +static FILE *fout; +static char *filename; +static int curr_rte_num, target_rte_num; static double radius; +static inifile_t *ini; /* placeholders for options */ @@ -59,72 +57,46 @@ static char *radius_opt; static arglist_t bcr_args[] = { - {"index", &rtenum_opt, "Index of route to write (if more the one in source)", NULL, ARGTYPE_INT }, - {"name", &rtename_opt, "New name for the route", NULL, ARGTYPE_STRING }, - {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", NULL, ARGTYPE_FLOAT }, - {0, 0, 0, 0, 0} + {"index", &rtenum_opt, "Index of route to write (if more the one in source)", NULL, ARGTYPE_INT, "1", NULL }, + {"name", &rtename_opt, "New name for the route", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", ARGTYPE_FLOAT, ARG_NOMINMAX }, + ARG_TERMINATOR }; -void +static void bcr_init_radius(void) { if (radius_opt != NULL) /* preinitialize the earth radius */ { - radius = atof(radius_opt); - if (radius < 0) - fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); + radius = atof(radius_opt); + if (radius < 0) + fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); } else - radius = (double)R_EARTH; + radius = (double)R_EARTH; if (global_opts.verbose_status > 0) - printf(MYNAME ": We calculate with radius %f meters.\n", radius); + printf(MYNAME ": We calculate with radius %f meters.\n", radius); } static void bcr_rd_init(const char *fname) { filename = xstrdup(fname); - fin = xfopen(fname, "r", MYNAME); + ini = inifile_init(fname, MYNAME); bcr_init_radius(); } static void bcr_rd_deinit(void) { - fclose(fin); + inifile_done(ini); xfree(filename); } /* ------------------------------------------------------------*/ -char * -bcr_next_char(const char *buff) -{ - char *result = (char *)buff; - while (*result > '\0' && *result <= ' ') result++; /* trim leading spaces */ - return result; -} - -waypoint * -bcr_find_waypt(const char *name, route_head *route) /* find a waypt by name, create new */ -{ /* if not found */ - waypoint *wpt; - queue *elem, *tmp; - - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - wpt = (waypoint *) elem; - if (0 == strcmp(wpt->shortname, name)) - return wpt; - } - wpt = waypt_new(); - wpt->shortname = xstrdup(name); - - return wpt; -} - -void +static void bcr_create_waypts_from_route(route_head *route) { waypoint *wpt; @@ -137,7 +109,7 @@ bcr_create_waypts_from_route(route_head *route) } } -void +static void bcr_wgs84_to_mercator(const double lat, const double lon, int *north, int *east) { double N, E; @@ -161,185 +133,68 @@ bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) *lon = (double)east * (double)180 / (radius * M_PI); } -static int -bcr_sort_route_by_index_cb(const void *a, const void *b) -{ - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; - return wa->centiseconds - wb->centiseconds; -} - -route_head * -bcr_sort_route_by_index(route_head *route) -{ - route_head *result; - queue *elem, *tmp; - waypoint **list; - waypoint *wpt; - int i; - int count = route->rte_waypt_ct; - - if (count == 0) return (route); /* nothing to do */ - - result = route_head_alloc(); - result->rte_name = xstrdup(route->rte_name); - route_add_head(result); - - list = (waypoint **) xcalloc(route->rte_waypt_ct, sizeof(*list)); - i = 0; - QUEUE_FOR_EACH((queue *)&route->waypoint_list, elem, tmp) - { - wpt = (waypoint *)elem; - list[i++] = wpt; - } - qsort(list, route->rte_waypt_ct, sizeof(*list), bcr_sort_route_by_index_cb); - for (i=0; icentiseconds = 0; /* reset our index container */ - route_add_wpt(result, waypt_dupe(wpt)); - route_del_wpt(route, wpt); - } - - xfree(list); - route_del_head(route); - - return result; -} - /* ------------------------------------------------------------- */ static void bcr_data_read(void) { - char buff[1024]; - char *src; - int section = SEC_UNKNOWN; - char *c, *cx, *ctemp; int index; - int mlat, mlon; /* mercator data */ - double xalt; - int line, skip; - + char *str; route_head *route; - waypoint *wpt; route = route_head_alloc(); - route_add_head(route); - line = skip = 0; - src = NULL; + if ((str = inifile_readstr(ini, "client", "routename"))) + route->rte_name = xstrdup(str); + + route_add_head(route); + + for (index = 1; index > 0; index ++) { - while (NULL != fgets(buff, sizeof(buff), fin)) - { - line++; - - c = buff; /* trim the end of the buffer */ - cx = c + strlen(c) - 1; - while ((cx > c) && (*cx <= ' ')) - { - *cx = '\0'; - cx--; - } - if (src != NULL) xfree(src); - - src = str_iso8859_1_to_utf8(buff); - /* !! buff is now free and can be used */ - - c = bcr_next_char(src); /* skip spaces */ - if (*c == '\0') continue; /* skip empty lines */ - - if (*c == '[') /* new section */ - { - skip = 0; + char station[32]; + char *str; + int mlat, mlon; /* mercator data */ + double xalt; + waypoint *wpt; - c = bcr_next_char(++c); - cx = strchr(c, ']'); - if (cx == NULL) fatal(MYNAME ": error in file structure (\"]\" expected)!\n"); + snprintf(station, sizeof(station), "STATION%d", index); + if (NULL == (str = inifile_readstr(ini, "coordinates", station))) break; - *cx = '\0'; - if (strcmp(c, "CLIENT") == 0) section = SEC_CLIENT; - else if (strcmp(c, "ROUTE") == 0) section = SEC_ROUTE; - else if (strcmp(c, "DESCRIPTION") == 0) section = SEC_DESCR; - else if (strcmp(c, "COORDINATES") == 0) section = SEC_COORD; - else - { - printf(MYNAME ": unknown section \"%s\".\n", c); - skip = 1; - } - continue; - } - - if (skip != 0) continue; - - cx = strchr(c, '='); - if (cx == NULL) continue; - - *cx++ = '\0'; /* delimit in key and data */ - - if ((section == SEC_CLIENT) && (strcmp(c, "ROUTENAME") == 0)) - { - route->rte_name = xstrdup(cx); - } - else - { - if (strncmp(c, "STATION", 7) != 0) continue; - index = atoi(c+7); - - /* bcr_find_waypt(... creates new waypoint, if not in queue */ + if (2 != sscanf(str, "%d,%d", &mlon, &mlat)) + fatal(MYNAME ": structure error at %s (Coordinates)!\n", station); + + wpt = waypt_new(); - switch(section) + wpt->shortname = xstrdup(station); + bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); + + if (NULL != (str = inifile_readstr(ini, "client", station))) { - case SEC_CLIENT: - wpt = bcr_find_waypt(c, route); - wpt->centiseconds = index; - ctemp = strchr(cx, ','); - if (ctemp != NULL) *ctemp = ' '; - if (2 != sscanf(cx, "%s %lf", buff, &xalt)) - fatal(MYNAME ": structure error on line %d!\n(data: %s=%s)\n", line, c, cx); -#if 0 - if (xalt != 999999999) - wpt->altitude = xalt / 3.2808; /* convert feet to meters */ -#endif - route_add_wpt(route, wpt); + char *cx; - if (case_ignore_strcmp(buff, "standort") == 0) - wpt->icon_descr = mps_find_desc_from_icon_number(18, MAPSOURCE); - else if (case_ignore_strcmp(buff, "Town") == 0) - wpt->icon_descr = mps_find_desc_from_icon_number(69, MAPSOURCE); - else - printf(MYNAME ": Unknown icon \"%s\" found. Please report.\n", buff); - break; - - case SEC_DESCR: - wpt = bcr_find_waypt(c, route); - wpt->centiseconds = index; + cx = strchr(str, ','); + if (cx == NULL) + fatal(MYNAME ": structure error at %s (Client)!\n", station); + *cx++ = '\0'; - ctemp = strchr(cx, '@'); - if (ctemp != NULL) - { - *ctemp-- = '\0'; - if (*ctemp == ',') *ctemp = '\0'; + xalt = atof(cx); + if (xalt != 999999999) { + wpt->altitude = FEET_TO_METERS(xalt); } - wpt->description = xstrdup(cx); - break; - - case SEC_COORD: - wpt = bcr_find_waypt(c, route); - wpt->centiseconds = index; - if (2 != sscanf(cx, "%d,%d", &mlon, &mlat)) - fatal(MYNAME ": structure error on line %d!\n", line); - - bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); - case SEC_ROUTE: - break; + + if (case_ignore_strcmp(str, "Standort") == 0) + wpt->icon_descr = gt_find_desc_from_icon_number(18, MAPSOURCE, NULL); + else if (case_ignore_strcmp(str, "Town") == 0) + wpt->icon_descr = gt_find_desc_from_icon_number(69, MAPSOURCE, NULL); + else + warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str); } - } + + if (NULL != (str = inifile_readstr(ini, "description", station))) + wpt->description = xstrdup(str); + + route_add_wpt(route, wpt); } - if (src != NULL) xfree(src); - src = NULL; - - route = bcr_sort_route_by_index(route); bcr_create_waypts_from_route(route); } @@ -349,7 +204,7 @@ static void bcr_wr_init(const char *fname) { filename = xstrdup(fname); - fout = xfopen(fname, "w", MYNAME); + fout = xfopen(fname, "wb", MYNAME); bcr_init_radius(); } @@ -374,14 +229,18 @@ void bcr_write_line(FILE *fout, const char *key, int *index, const char *value) { if (value == NULL) /* this is mostly used in the world of windows */ { /* so we respectfully add a CR/LF on each line */ - fprintf(fout, "%s\x0d\n", key); + fprintf(fout, "%s\r\n", key); } else { + char *tmp; + + tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); if (index != NULL) - fprintf(fout, "%s%d=%s\x0d\n", key, *index, value); + fprintf(fout, "%s%d=%s\r\n", key, *index, tmp); else - fprintf(fout, "%s=%s\x0d\n", key, value); + fprintf(fout, "%s=%s\r\n", key, tmp); + xfree(tmp); } } @@ -420,7 +279,7 @@ bcr_route_header(const route_head *route) strncpy(symbol, "Standort", sizeof(symbol)); if (wpt->icon_descr != 0) { - icon = mps_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); if ((icon >= 69) && (icon <= 72)) strncpy(symbol, "Town", sizeof(symbol)); } @@ -499,6 +358,6 @@ ff_vecs_t bcr_vecs = { bcr_data_read, bcr_data_write, NULL, - bcr_args + bcr_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; - diff --git a/brauniger_iq.c b/brauniger_iq.c index e42d820c2..30905e523 100644 --- a/brauniger_iq.c +++ b/brauniger_iq.c @@ -19,11 +19,10 @@ */ #include "defs.h" -#include "jeeps/gpsserial.h" +#include "gbser.h" #include -static int32 fd; -static char *port; +static void *serial_handle; #define MYNAME "BRAUNIGER-IQ" #define PRESTRKNAME "PRESALTTRK" @@ -50,35 +49,25 @@ static enum { static const int reqd_bytes[num_states] = { 6, 1, 2, 2, 25, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1 }; -static void rd_init(const char *fname) -{ - port = xstrdup(fname); - - // Fortunately the instruments use the same serial settings as the Garmin - // GPS receivers (9600-8-N) so we can use jeeps and hence we don't need - // to worry about OS dependencies here. - if (!GPS_Serial_On(port, &fd)) { - fatal(MYNAME ": Can't initialise port '%s'\n", port); - } +static void rd_init(const char *fname) { + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_port(serial_handle, 9600, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } } -static void rd_deinit(void) -{ - if (!GPS_Serial_Off(port, fd)) { - fatal(MYNAME ": Can't shut down port '%s'\n", port); - } - if (!GPS_Serial_Close(fd, port)) { - fatal(MYNAME ": Can't close port '%s'\n", port); - } - xfree(port); +static void rd_deinit(void) { + gbser_deinit(serial_handle); + serial_handle = NULL; } /** * Process a data record. * @return zero when all expected data has been received */ -static int process_data(const unsigned char *data) -{ +static int process_data(const unsigned char *data) { static int remaining = 100; static struct tm tm; static time_t start, creation; @@ -89,181 +78,179 @@ static int process_data(const unsigned char *data) int i; if (global_opts.debug_level >= 3) { - for (i = 0; i < reqd_bytes[state]; i++) { - printf("%.2x ", data[i]); - } - puts(""); + for (i = 0; i < reqd_bytes[state]; i++) { + printf("%.2x ", data[i]); + } + puts(""); } remaining -= reqd_bytes[state]; switch (state) { case st_sync: - if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { - fatal(MYNAME ": Could not synchronise\n"); - } - break; + if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { + fatal(MYNAME ": Could not synchronise\n"); + } + break; case st_fl_num: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Flight Number: %d\n", data[0]); - } - break; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Flight Number: %d\n", data[0]); + } + break; case st_data_len: - remaining = (data[0] << 8) + data[1] - 2; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Data Length: %d\n", remaining); - } - break; + remaining = (data[0] << 8) + data[1] - 2; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Data Length: %d\n", remaining); + } + break; case st_ser_num: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); - } - break; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); + } + break; case st_pilot_name: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Pilot Name: %.25s\n", data); - } - break; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Pilot Name: %.25s\n", data); + } + break; case st_start_date: - i = (data[0] << 8) + data[1]; - tm.tm_mday = i / 100; - tm.tm_mon = (i % 100) - 1; - break; + i = (data[0] << 8) + data[1]; + tm.tm_mday = i / 100; + tm.tm_mon = (i % 100) - 1; + break; case st_start_year: - tm.tm_year = ((data[0] << 8) + data[1]) - 1900; - break; + tm.tm_year = ((data[0] << 8) + data[1]) - 1900; + break; case st_max_alt_1: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); - } - break; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); + } + break; case st_max_alt_2: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); - } - break; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); + } + break; case st_max_climb: - if (global_opts.debug_level >= 1) { - i = (data[0] << 8) + data[1]; - printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); - } - break; + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); + } + break; case st_flight_dur: - if (global_opts.debug_level >= 1) { - i = (data[0] << 8) + data[1]; - printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); - } - break; + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); + } + break; case st_log_ival: - interval = data[0]; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Logging Interval: %ds\n", interval); - } - break; + interval = data[0]; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Logging Interval: %ds\n", interval); + } + break; case st_start_time: - i = (data[0] << 8) + data[1]; - tm.tm_hour = i / 100; - tm.tm_min = (i % 100) - 1; - tm.tm_sec = 0; - creation = start = mktime(&tm); - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Start Time: %s", ctime(&start)); - } - break; + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + tm.tm_sec = 0; + creation = start = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Start Time: %s", ctime(&start)); + } + break; case st_end_time: - i = (data[0] << 8) + data[1]; - tm.tm_hour = i / 100; - tm.tm_min = (i % 100) - 1; - finish = mktime(&tm); - if (global_opts.debug_level >= 1) { - printf(MYNAME ": End Time: %s", ctime(&finish)); - } - if (remaining) { - track = route_head_alloc(); - track->rte_name = xstrdup(PRESTRKNAME); - track->rte_desc = xstrdup("Brauniger-IQ Barograph"); - track_add_head(track); - } else { - warning(MYNAME ": No barograph recorded for this flight\n"); - } - break; + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + finish = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": End Time: %s", ctime(&finish)); + } + if (remaining) { + track = route_head_alloc(); + track->rte_name = xstrdup(PRESTRKNAME); + track->rte_desc = xstrdup("Brauniger-IQ Barograph"); + track_add_head(track); + } else { + warning(MYNAME ": No barograph recorded for this flight\n"); + } + break; case st_sample_alt: - wpt = waypt_new(); - wpt->latitude = wpt->longitude = 0.0; - wpt->creation_time = creation; - creation += interval; - wpt->altitude = (data[0] << 8) + data[1]; - route_add_wpt(track, wpt); - if (global_opts.debug_level >= 2) { - printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); - } - break; + wpt = waypt_new(); + wpt->latitude = wpt->longitude = 0.0; + wpt->creation_time = creation; + creation += interval; + wpt->altitude = (data[0] << 8) + data[1]; + track_add_wpt(track, wpt); + if (global_opts.debug_level >= 2) { + printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); + } + break; case st_sample_spd: - if (global_opts.debug_level >= 2) { - printf("Airspeed=%dkmh\n", data[0]); - } - state = st_sample_alt; - return remaining; + if (global_opts.debug_level >= 2) { + printf("Airspeed=%dkmh\n", data[0]); + } + state = st_sample_alt; + return remaining; default: - fatal(MYNAME ": Bad internal state\n"); + fatal(MYNAME ": Bad internal state\n"); } state++; return remaining; } -static void data_read(void) -{ +static void data_read(void) { unsigned char ibuf[25]; - int32 rd_cnt, ofs; + int rd_cnt; if (global_opts.debug_level >= 0) { - puts(MYNAME ": Select recorded flight in memo mode."); - puts(MYNAME ": Press Memo button for two seconds..."); + puts(MYNAME ": Select recorded flight in memo mode."); + puts(MYNAME ": Press Memo button for two seconds..."); } + // Wait until something arrives - while (!GPS_Serial_Wait(fd)); if (global_opts.debug_level >= 0) { - puts(MYNAME ": Downloading flight..."); + puts(MYNAME ": Downloading flight..."); } - // Read data until there is none left to read + + // Read data until there is none left to read state = st_sync; - ofs = 0; - do { - if (0 > (rd_cnt = GPS_Serial_Read(fd, ibuf + ofs, reqd_bytes[state] - ofs))) { - fatal(MYNAME ": Error reading port '%s', %s\n", port, strerror(errno)); - } - if (reqd_bytes[state] == rd_cnt + ofs) { - if (!process_data(ibuf)) { - if (global_opts.debug_level >= 0) { - puts(MYNAME " ...Finished"); + for (;;) { + /* wait up to 5 seconds for more data */ + rd_cnt = gbser_read_wait(serial_handle, ibuf, reqd_bytes[state], 5000); + if (rd_cnt < 0) { + fatal(MYNAME ": Serial error\n"); + } else if (rd_cnt < reqd_bytes[state]) { + fatal(MYNAME ": Incomplete download\n"); + } + + if (!process_data(ibuf)) { + if (global_opts.debug_level >= 0) { + puts(MYNAME " ...Finished"); + } + return; } - return; - } - ofs = 0; - } else { - ofs += rd_cnt; } - } while (GPS_Serial_Wait(fd)); - fatal(MYNAME ": Incomplete download\n"); } static arglist_t brauniger_iq_args[] = { - {0, 0, 0, 0, 0} + ARG_TERMINATOR }; ff_vecs_t brauniger_iq_vecs = { @@ -276,5 +263,6 @@ ff_vecs_t brauniger_iq_vecs = { data_read, NULL, NULL, - brauniger_iq_args + brauniger_iq_args, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; diff --git a/cet.c b/cet.c new file mode 100644 index 000000000..abc8b64b6 --- /dev/null +++ b/cet.c @@ -0,0 +1,360 @@ +/* + + Character encoding transformation - basics + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "cet.h" + +#include +#include +#include +#include + +/* ! ALL vec PARAMETERS HAVE TO BE A VALID POINTER TO A cet_cs_vec_t RECORD ! */ + +/* =========================================================================== */ +/* %%% single character or value transmission %%% */ +/* --------------------------------------------------------------------------- */ + +/* %%% cet_char_to_ucs4 %%% + * + * single character to UCS-4 code %%% + * return values: 0 if convertable character, otherwise 1 + */ + +int +cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value) +{ + int trash, c; + int *dest; + + c = ((unsigned char)src & 0xFF); + dest = (value != NULL) ? value : &trash; + + *dest = c; + c -= vec->ucs4_offset; + + if (c < 0) return CET_SUCESS; + else if ((c >= vec->ucs4_count) || (vec->ucs4_map[c] == -1)) return CET_ERROR; + else + { + *dest = vec->ucs4_map[c]; + return CET_SUCESS; + } +} + +/* %%% cet_ucs4_to_utf8 %%% + * + * convert single UCS-4 value into UTF-8 sequence + * + * return values: >= 0: length of produced UTF-8 sequence + * < 0: -bytes more needed in target space + */ + +int +cet_ucs4_to_utf8(char *dest, size_t dest_size, int value) +{ + int result; + unsigned char trash[16]; + unsigned char *c; + + c = (dest != NULL) ? (unsigned char *) dest : trash; + + if ((value & 0xffffff80) == 0) /* <= 7 bits */ + { + if (dest_size < 1) return (dest_size - 1); + *c++ = value; + result = 1; + } + else if ((value & 0xfffff800) == 0) /* <= 11 bits */ + { + if (dest_size < 2) return (dest_size - 2); + *c++ = (0xc0 | (value >> 6)); + *c++ = (0x80 | (value & 0x3f)); + result = 2; + + } + else if ((value & 0xffff0000) == 0) /* <= 16 bits */ + { + if (dest_size < 3) return (dest_size - 3); + *c++ = (0xe0 | (value >> 12)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 3; + } + else if ((value & 0xffe00000) == 0) /* <= 21 bits */ + { + if (dest_size < 4) return (dest_size - 4); + *c++ = (0xf0 | (value >> 18)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 4; + } + else if ((value & 0xfc000000) == 0) /* <= 26 bits */ + { + if (dest_size < 5) return (dest_size - 5); + *c++ = (0xf8 | (value >> 24)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 5; + } + else if ((value & 0x80000000) == 0) /* <= 31 bits */ + { + if (dest_size < 6) return (dest_size - 6); + *c++ = (0xfc | (value >> 30)); + *c++ = (0x80 | ((value >> 24) & 0x3f)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 6; + } + else + { + return 0; /* Value = -1 */ + } + return result; +} + +/* %%% cet_utf8_to_ucs4 %%% + * + * decode single UTF-8 sequence into UCS-4 value + * + * return values: 0 if success, otherwise 1 + */ +int +cet_utf8_to_ucs4(const char *str, int *bytes, int *value) +{ + unsigned char *cp = (unsigned char *)str; + + if (*cp < 0x80) + { + if (bytes != NULL) *bytes = 1; + if (value != NULL) *value = *cp; + return CET_SUCESS; + } + else + { + unsigned char bits = 0xc0; + unsigned char mask = 0xe0; + int len = 0; + + for (len = 1; len <= 6; len++) /* outer loop, test UTF-8 frame */ + { + if ((*cp & mask) == bits) + { + int i = len; + while (i-- > 0) + { + cp++; + if ((*cp & 0xc0) != 0x80) break; /* invalid */ + else if (i == 0) /* all valid */ + { + char *c = (char *)str; /* found valid sequence, now storing value */ + int res = *c++ & (mask ^ 0xFF); + i = len; + while (i-- > 0) + res = (res << 6) | (*c++ & 0x3f); + + if (bytes != NULL) *bytes = len + 1; + if (value != NULL) *value = res; + return CET_SUCESS; + } + } + } + bits = (bits >> 1) | 0x80; + mask = (mask >> 1) | 0x80; + } + } + if (bytes != NULL) *bytes = 1; + if (value != NULL) *value = *cp; + return CET_ERROR; /* not valid */ +} + +/* %%% cet_ucs4_to_char %%% + * + * convert single UCS-4 value to original character from CS + * + * return values: coverted character or "CET_NOT_CONVERTABLE_DEFAULT" + * if not possible + */ +short +cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec) +{ + cet_ucs4_link_t *link; + + if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) + { + int i = 0; + int j = vec->ucs4_links - 1; /* validate ucs value against vec */ + while (i <= j) + { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) i = a + 1; + else if (x > value) j = a - 1; + else return link[a].origin; + } + } + + if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) /* can be NULL */ + { + int i = 0; + int j = vec->ucs4_extras - 1; + while (i <= j) + { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) i = a + 1; + else if (x > value) j = a - 1; + else return link[a].origin; + } + } + + if (value < vec->ucs4_offset + vec->ucs4_count) + return (char)value & 0xFF; + else + return CET_NOT_CONVERTABLE_DEFAULT; +} + +/* %%% cet_utf8_to_char %%% + * + * Convert single UTF-8 sequence directly into associated characted + * by given character set. + */ + +short +cet_utf8_to_char(const char *str, const cet_cs_vec_t *vec, /* out */ int *bytes, int *value) +{ + int b, v; + + cet_utf8_to_ucs4(str, &b, &v); /* decode UTF-8 sequence */ + + if (bytes != NULL) *bytes = b; + if (value != NULL) *value = v; + + return cet_ucs4_to_char(v, vec); +} + +/* =========================================================================== */ +/* %%% full string transformation %%% */ +/* =========================================================================== */ + +/* %%% cet_str_utf8_to_any %%% + * + * Converts a UTF-8 string to given character set + */ +char * +cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec) +{ + char *c = (char *)src; + int len; + char *res, *dest, *cend; + + if (c == NULL) return NULL; + + len = strlen(c); + res = dest = xmalloc(len + 1); /* target will become smaller or equal length */ + + cend = c + len; + + while (c < cend) + { + int bytes; + *dest++ = cet_utf8_to_char(c, vec, &bytes, NULL); + c += bytes; + } + *dest = '\0'; + + return res; +} + + +/* %%% cet_str_any_to_utf8 %%% + * + * Converts a string from given character set to UTF-8 + */ +char * +cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec) +{ + int len, value; + char *result, *cin, *cout; + char temp = CET_NOT_CONVERTABLE_DEFAULT; + + cin = (char *)src; + if (cin == NULL) return NULL; + + len = 0; + while (*cin != '\0') /* determine length of resulting UTF-8 string */ + { + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) + cet_char_to_ucs4(temp, vec, &value); + len += cet_ucs4_to_utf8(NULL, 6, value); + } + + result = cout = xmalloc(len + 1); + cin = (char *)src; + + while (*cin != '\0') + { + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) + cet_char_to_ucs4(temp, vec, &value); + cout += cet_ucs4_to_utf8(cout, 6, value); + } + *cout = '\0'; + return result; +} + +/* %%% cet_str_uni_to_utf8 %%% + * + * Converts an unicode string to UTF-8 + */ +char * +cet_str_uni_to_utf8(const short *src, const int length) +{ + int i, len; + unsigned short *cin; + char *res, *cout; + + if (src == NULL) return NULL; + + len = 0; + i = length; + cin = (unsigned short *)src; + + while (i-- > 0) + len += cet_ucs4_to_utf8(NULL, 6, le_read16(cin++)); + + res = cout = xmalloc(len + 1); + cin = (unsigned short *)src; + i = length; + + while (i-- > 0) + cout += cet_ucs4_to_utf8(cout, 6, le_read16(cin++)); + + *cout = '\0'; + + return res; +} diff --git a/cet.h b/cet.h new file mode 100644 index 000000000..fdc702623 --- /dev/null +++ b/cet.h @@ -0,0 +1,71 @@ +/* + + Character encoding transformation - basics header + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#ifndef CET_H +#define CET_H + +#include +#include + +#define CET_ERROR 1 +#define CET_SUCESS 0 + +typedef struct cet_ucs4_link_s +{ + int value; /* UCS-4 value */ + short origin; /* associeted character */ +} cet_ucs4_link_t; + +typedef struct cet_cs_vec_s +{ + const char *name; /* name of character set */ + const char **alias; /* alias table */ + int (*decode)(const char *, int *); /* ... to UCS-4 decoder !FUTURE! */ + short (*encode)(const int); /* UCS-4 to ... encoder !FUTURE! */ + const int *ucs4_map; /* char to UCS-4 value table */ + const int ucs4_offset; /* first non standard character */ + const int ucs4_count; /* values in table */ + const cet_ucs4_link_t *ucs4_link; /* UCS-4 to char backward links */ + const int ucs4_links; /* number of links */ + const cet_ucs4_link_t *ucs4_extra; /* Non standard UCS-4 to ... */ + const int ucs4_extras; /* number of extra links */ + struct cet_cs_vec_s *next; +} cet_cs_vec_t; + +/* single char/value transmission */ + +int cet_utf8_to_ucs4(const char *str, int *bytes, int *value); +int cet_ucs4_to_utf8(char *dest, size_t dest_size, int value); + +/* single char/value transmission - vec based */ + +int cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value); +short cet_utf8_to_char(const char *str, const cet_cs_vec_t *vecint, int *bytes, int *value); +short cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec); + +/* string to string - vector based */ + +char *cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec); +char *cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec); + +char *cet_str_uni_to_utf8(const short *src, const int length); + +#endif diff --git a/cet/ansi_x3_4_1968.h b/cet/ansi_x3_4_1968.h new file mode 100644 index 000000000..700c091b7 --- /dev/null +++ b/cet/ansi_x3_4_1968.h @@ -0,0 +1,305 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ANSI_X3.4-1968" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ansi_x3_4_1968_h +#define ansi_x3_4_1968_h + +#define cet_cs_name_ansi_x3_4_1968 "US-ASCII" + +const char *cet_cs_alias_ansi_x3_4_1968[] = +{ + "ANSI_X3.4-1968", "367", "ANSI_X3.4-1986", "ASCII", + "CP367", "csASCII", "IBM367", "ISO646-US", + "ISO646.1991-IRV", "iso-ir-6", "ISO_646.irv:1991", "us", + NULL +}; + +#define cet_ucs4_ofs_ansi_x3_4_1968 128 +#define cet_ucs4_cnt_ansi_x3_4_1968 1 + +const int cet_ucs4_map_ansi_x3_4_1968[cet_ucs4_cnt_ansi_x3_4_1968]; + +#define cet_ucs4_to_ansi_x3_4_1968_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ansi_x3_4_1968_links[cet_ucs4_to_ansi_x3_4_1968_ct]; + +// #define cet_ucs4_to_ansi_x3_4_1968_extra_ct 200 + +const cet_ucs4_link_t cet_ucs4_to_ansi_x3_4_1968_extra[] = +/* ------------------------------------------*/ +/* !!! sorted by UCS-4 value !!! */ +/* ------------------------------------------*/ +{ + {0x00c0, (unsigned char) 'A'}, // latin capital letter a with grave + {0x00c1, (unsigned char) 'A'}, // latin capital letter a with acute + {0x00C2, (unsigned char) 'A'}, // latin capital letter a with circumflex + {0x00C3, (unsigned char) 'A'}, // latin capital letter a with tilde + {0x00C4, (unsigned char) 'A'}, // latin capital letter a with diaeresis + {0x00C5, (unsigned char) 'A'}, // latin capital letter a with ring above + {0x00C7, (unsigned char) 'C'}, // latin capital letter c with cedilla + {0x00C8, (unsigned char) 'E'}, // latin capital letter e with grave + {0x00C9, (unsigned char) 'E'}, // latin capital letter e with acute + {0x00CA, (unsigned char) 'E'}, // latin capital letter e with circumflex + {0x00CB, (unsigned char) 'E'}, // latin capital letter e with diaeresis + {0x00CC, (unsigned char) 'I'}, // latin capital letter i with grave + {0x00CD, (unsigned char) 'I'}, // latin capital letter i with acute + {0x00CE, (unsigned char) 'I'}, // latin capital letter i with circumflex + {0x00CF, (unsigned char) 'I'}, // latin capital letter i with diaeresis + {0x00D1, (unsigned char) 'N'}, // latin capital letter n with tilde + {0x00D2, (unsigned char) 'O'}, // latin capital letter o with grave + {0x00D3, (unsigned char) 'O'}, // latin capital letter o with acute + {0x00D4, (unsigned char) 'O'}, // latin capital letter o with circumflex + {0x00D5, (unsigned char) 'O'}, // latin capital letter o with tilde + {0x00D6, (unsigned char) 'O'}, // latin capital letter o with diaeresis + {0x00D8, (unsigned char) 'O'}, // latin capital letter o with stroke + {0x00D9, (unsigned char) 'U'}, // latin capital letter u with grave + {0x00DA, (unsigned char) 'U'}, // latin capital letter u with acute + {0x00DB, (unsigned char) 'U'}, // latin capital letter u with circumflex + {0x00DC, (unsigned char) 'U'}, // latin capital letter u with diaeresis + {0x00DD, (unsigned char) 'Y'}, // latin capital letter y with acute + {0x00E0, (unsigned char) 'a'}, // latin small letter a with grave + {0x00E1, (unsigned char) 'a'}, // latin small letter a with acute + {0x00E2, (unsigned char) 'a'}, // latin small letter a with circumflex + {0x00E3, (unsigned char) 'a'}, // latin small letter a with tilde + {0x00E4, (unsigned char) 'a'}, // latin small letter a with diaeresis + {0x00E5, (unsigned char) 'a'}, // latin small letter a with ring above + {0x00E7, (unsigned char) 'c'}, // latin small letter c with cedilla + {0x00E8, (unsigned char) 'e'}, // latin small letter e with grave + {0x00E9, (unsigned char) 'e'}, // latin small letter e with acute + {0x00EA, (unsigned char) 'e'}, // latin small letter e with circumflex + {0x00EB, (unsigned char) 'e'}, // latin small letter e with diaeresis + {0x00EC, (unsigned char) 'i'}, // latin small letter i with grave + {0x00ED, (unsigned char) 'i'}, // latin small letter i with acute + {0x00EE, (unsigned char) 'i'}, // latin small letter i with circumflex + {0x00EF, (unsigned char) 'i'}, // latin small letter i with diaeresis + {0x00F1, (unsigned char) 'n'}, // latin small letter n with tilde + {0x00F2, (unsigned char) 'o'}, // latin small letter o with grave + {0x00F3, (unsigned char) 'o'}, // latin small letter o with acute + {0x00F4, (unsigned char) 'o'}, // latin small letter o with circumflex + {0x00F5, (unsigned char) 'o'}, // latin small letter o with tilde + {0x00F6, (unsigned char) 'o'}, // latin small letter o with diaeresis + {0x00F8, (unsigned char) 'o'}, // latin small letter o with stroke + {0x00F9, (unsigned char) 'u'}, // latin small letter u with grave + {0x00FA, (unsigned char) 'u'}, // latin small letter u with acute + {0x00FB, (unsigned char) 'u'}, // latin small letter u with circumflex + {0x00FC, (unsigned char) 'u'}, // latin small letter u with diaeresis + {0x00FD, (unsigned char) 'y'}, // latin small letter y with acute + {0x00FF, (unsigned char) 'y'}, // latin small letter y with diaeresis + {0x0100, (unsigned char) 'A'}, // latin capital letter a with macron + {0x0101, (unsigned char) 'a'}, // latin small letter a with macron + {0x0102, (unsigned char) 'A'}, // latin capital letter a with breve + {0x0103, (unsigned char) 'a'}, // latin small letter a with breve + {0x0104, (unsigned char) 'A'}, // latin capital letter a with ogonek + {0x0105, (unsigned char) 'a'}, // latin small letter a with ogonek + {0x0106, (unsigned char) 'C'}, // latin capital letter c with acute + {0x0107, (unsigned char) 'c'}, // latin small letter c with acute + {0x0108, (unsigned char) 'C'}, // latin capital letter c with circumflex + {0x0109, (unsigned char) 'c'}, // latin small letter c with circumflex + {0x010A, (unsigned char) 'C'}, // latin capital letter c with dot above + {0x010B, (unsigned char) 'c'}, // latin small letter c with dot above + {0x010C, (unsigned char) 'C'}, // latin capital letter c with caron + {0x010D, (unsigned char) 'c'}, // latin small letter c with caron + {0x010E, (unsigned char) 'D'}, // latin capital letter d with caron + {0x010F, (unsigned char) 'd'}, // latin small letter d with caron + {0x0110, (unsigned char) 'D'}, // latin capital letter d with stroke + {0x0111, (unsigned char) 'd'}, // latin small letter d with stroke + {0x0112, (unsigned char) 'E'}, // latin capital letter e with macron + {0x0113, (unsigned char) 'e'}, // latin small letter e with macron + {0x0116, (unsigned char) 'E'}, // latin capital letter e with dot above + {0x0117, (unsigned char) 'e'}, // latin small letter e with dot above + {0x0118, (unsigned char) 'E'}, // latin capital letter e with ogonek + {0x0119, (unsigned char) 'e'}, // latin small letter e with ogonek + {0x011A, (unsigned char) 'E'}, // latin capital letter e with caron + {0x011B, (unsigned char) 'e'}, // latin small letter e with caron + {0x011C, (unsigned char) 'G'}, // latin capital letter g with circumflex + {0x011D, (unsigned char) 'g'}, // latin small letter g with circumflex + {0x011E, (unsigned char) 'G'}, // latin capital letter g with breve + {0x011F, (unsigned char) 'g'}, // latin small letter g with breve + {0x0120, (unsigned char) 'G'}, // latin capital letter g with dot above + {0x0121, (unsigned char) 'g'}, // latin small letter g with dot above + {0x0122, (unsigned char) 'G'}, // latin capital letter g with cedilla + {0x0123, (unsigned char) 'g'}, // latin small letter g with cedilla + {0x0124, (unsigned char) 'H'}, // latin capital letter h with circumflex + {0x0125, (unsigned char) 'h'}, // latin small letter h with circumflex + {0x0126, (unsigned char) 'H'}, // latin capital letter h with stroke + {0x0127, (unsigned char) 'h'}, // latin small letter h with stroke + {0x0128, (unsigned char) 'I'}, // latin capital letter i with tilde + {0x0129, (unsigned char) 'i'}, // latin small letter i with tilde + {0x012A, (unsigned char) 'I'}, // latin capital letter i with macron + {0x012B, (unsigned char) 'i'}, // latin small letter i with macron + {0x012E, (unsigned char) 'I'}, // latin capital letter i with ogonek + {0x012F, (unsigned char) 'i'}, // latin small letter i with ogonek + {0x0130, (unsigned char) 'I'}, // latin capital letter i with dot above + {0x0134, (unsigned char) 'J'}, // latin capital letter j with circumflex + {0x0135, (unsigned char) 'j'}, // latin small letter j with circumflex + {0x0136, (unsigned char) 'K'}, // latin capital letter k with cedilla + {0x0137, (unsigned char) 'k'}, // latin small letter k with cedilla + {0x0139, (unsigned char) 'L'}, // latin capital letter l with acute + {0x013A, (unsigned char) 'l'}, // latin small letter l with acute + {0x013B, (unsigned char) 'L'}, // latin capital letter l with cedilla + {0x013C, (unsigned char) 'l'}, // latin small letter l with cedilla + {0x013D, (unsigned char) 'L'}, // latin capital letter l with caron + {0x013E, (unsigned char) 'l'}, // latin small letter l with caron + {0x0141, (unsigned char) 'L'}, // latin capital letter l with stroke + {0x0142, (unsigned char) 'l'}, // latin small letter l with stroke + {0x0143, (unsigned char) 'N'}, // latin capital letter n with acute + {0x0144, (unsigned char) 'n'}, // latin small letter n with acute + {0x0145, (unsigned char) 'N'}, // latin capital letter n with cedilla + {0x0146, (unsigned char) 'n'}, // latin small letter n with cedilla + {0x0147, (unsigned char) 'N'}, // latin capital letter n with caron + {0x0148, (unsigned char) 'n'}, // latin small letter n with caron + {0x014C, (unsigned char) 'O'}, // latin capital letter o with macron + {0x014D, (unsigned char) 'o'}, // latin small letter o with macron + {0x0150, (unsigned char) 'O'}, // latin capital letter o with double acute + {0x0151, (unsigned char) 'o'}, // latin small letter o with double acute + {0x0154, (unsigned char) 'R'}, // latin capital letter r with acute + {0x0155, (unsigned char) 'r'}, // latin small letter r with acute + {0x0156, (unsigned char) 'R'}, // latin capital letter r with cedilla + {0x0157, (unsigned char) 'r'}, // latin small letter r with cedilla + {0x0158, (unsigned char) 'R'}, // latin capital letter r with caron + {0x0159, (unsigned char) 'r'}, // latin small letter r with caron + {0x015A, (unsigned char) 'S'}, // latin capital letter s with acute + {0x015B, (unsigned char) 's'}, // latin small letter s with acute + {0x015C, (unsigned char) 'S'}, // latin capital letter s with circumflex + {0x015D, (unsigned char) 's'}, // latin small letter s with circumflex + {0x015E, (unsigned char) 'S'}, // latin capital letter s with cedilla + {0x015F, (unsigned char) 's'}, // latin small letter s with cedilla + {0x0160, (unsigned char) 'S'}, // latin capital letter s with caron + {0x0161, (unsigned char) 's'}, // latin small letter s with caron + {0x0162, (unsigned char) 'T'}, // latin capital letter t with cedilla + {0x0163, (unsigned char) 't'}, // latin small letter t with cedilla + {0x0164, (unsigned char) 'T'}, // latin capital letter t with caron + {0x0165, (unsigned char) 't'}, // latin small letter t with caron + {0x0166, (unsigned char) 'T'}, // latin capital letter t with stroke + {0x0167, (unsigned char) 't'}, // latin small letter t with stroke + {0x0168, (unsigned char) 'U'}, // latin capital letter u with tilde + {0x0169, (unsigned char) 'u'}, // latin small letter u with tilde + {0x016A, (unsigned char) 'U'}, // latin capital letter u with macron + {0x016B, (unsigned char) 'u'}, // latin small letter u with macron + {0x016C, (unsigned char) 'U'}, // latin capital letter u with breve + {0x016D, (unsigned char) 'u'}, // latin small letter u with breve + {0x016E, (unsigned char) 'U'}, // latin capital letter u with ring above + {0x016F, (unsigned char) 'u'}, // latin small letter u with ring above + {0x0170, (unsigned char) 'U'}, // latin capital letter u with double acute + {0x0171, (unsigned char) 'u'}, // latin small letter u with double acute + {0x0172, (unsigned char) 'U'}, // latin capital letter u with ogonek + {0x0173, (unsigned char) 'u'}, // latin small letter u with ogonek + {0x0174, (unsigned char) 'W'}, // latin capital letter w with circumflex + {0x0175, (unsigned char) 'w'}, // latin small letter w with circumflex + {0x0176, (unsigned char) 'Y'}, // latin capital letter y with circumflex + {0x0177, (unsigned char) 'y'}, // latin small letter y with circumflex + {0x0178, (unsigned char) 'Y'}, // latin capital letter y with diaeresis + {0x0179, (unsigned char) 'Z'}, // latin capital letter z with acute + {0x017A, (unsigned char) 'z'}, // latin small letter z with acute + {0x017B, (unsigned char) 'Z'}, // latin capital letter z with dot above + {0x017C, (unsigned char) 'z'}, // latin small letter z with dot above + {0x017D, (unsigned char) 'Z'}, // latin capital letter z with caron + {0x017E, (unsigned char) 'z'}, // latin small letter z with caron + {0x1E02, (unsigned char) 'B'}, // latin capital letter b with dot above + {0x1E03, (unsigned char) 'b'}, // latin small letter b with dot above + {0x1E0A, (unsigned char) 'D'}, // latin capital letter d with dot above + {0x1E0B, (unsigned char) 'd'}, // latin small letter d with dot above + {0x1E1E, (unsigned char) 'F'}, // latin capital letter f with dot above + {0x1E1F, (unsigned char) 'f'}, // latin small letter f with dot above + {0x1E40, (unsigned char) 'M'}, // latin capital letter m with dot above + {0x1E41, (unsigned char) 'm'}, // latin small letter m with dot above + {0x1E56, (unsigned char) 'P'}, // latin capital letter p with dot above + {0x1E57, (unsigned char) 'p'}, // latin small letter p with dot above + {0x1E60, (unsigned char) 'S'}, // latin capital letter s with dot above + {0x1E61, (unsigned char) 's'}, // latin small letter s with dot above + {0x1E6A, (unsigned char) 'T'}, // latin capital letter t with dot above + {0x1E6B, (unsigned char) 't'}, // latin small letter t with dot above + {0x1E80, (unsigned char) 'W'}, // latin capital letter w with grave + {0x1E81, (unsigned char) 'w'}, // latin small letter w with grave + {0x1E82, (unsigned char) 'W'}, // latin capital letter w with acute + {0x1E83, (unsigned char) 'w'}, // latin small letter w with acute + {0x1E84, (unsigned char) 'W'}, // latin capital letter w with diaeresis + {0x1E85, (unsigned char) 'w'}, // latin small letter w with diaeresis + {0x1e94, (unsigned char) 'u'}, + {0x1EF2, (unsigned char) 'Y'}, // latin capital letter y with grave + {0x1EF3, (unsigned char) 'y'}, // latin small letter y with grave + {0x201c, (unsigned char) '"'}, + {0x201d, (unsigned char) '"'} +}; + +cet_cs_vec_t cet_cs_vec_ansi_x3_4_1968 = /* defined in cet.h */ +{ + cet_cs_name_ansi_x3_4_1968, /* name of character set */ + cet_cs_alias_ansi_x3_4_1968, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ansi_x3_4_1968, /* char to UCS-4 value table */ + cet_ucs4_ofs_ansi_x3_4_1968, /* first non standard character */ + cet_ucs4_cnt_ansi_x3_4_1968, /* number of values in table */ + + cet_ucs4_to_ansi_x3_4_1968_links, /* UCS-4 to char links */ + cet_ucs4_to_ansi_x3_4_1968_ct, /* number of links */ + + cet_ucs4_to_ansi_x3_4_1968_extra, /* hand made UCS-4 links */ + sizeof(cet_ucs4_to_ansi_x3_4_1968_extra) / sizeof(cet_ucs4_to_ansi_x3_4_1968_extra[0]), /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ansi_x3_4_1968_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/atarist.h b/cet/atarist.h new file mode 100644 index 000000000..b0403add4 --- /dev/null +++ b/cet/atarist.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "AtariST" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef atarist_h +#define atarist_h + +#define cet_cs_name_atarist "AtariST" + +const char *cet_cs_alias_atarist[] = +{ + "AtariST", NULL +}; + +#define cet_ucs4_ofs_atarist 128 +#define cet_ucs4_cnt_atarist 128 + +const int cet_ucs4_map_atarist[cet_ucs4_cnt_atarist] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x00df, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x00e3, 0x00f5, 0x00d8, 0x00f8, 0x0153, 0x0152, 0x00c0, 0x00c3, + 0x00d5, 0x00a8, 0x00b4, 0x2020, 0x00b6, 0x00a9, 0x00ae, 0x2122, + 0x0133, 0x0132, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, + 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05db, 0x05dc, 0x05de, 0x05e0, + 0x05e1, 0x05e2, 0x05e4, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, + 0x05df, 0x05da, 0x05dd, 0x05e3, 0x05e5, 0x00a7, 0x2038, 0x221e, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x03b8, 0x2126, 0x03b4, 0x222e, 0x03c6, 0x2208, 0x220f, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x00b3, 0x00af +}; + +#define cet_ucs4_to_atarist_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_atarist_links[cet_ucs4_to_atarist_ct] = +{ + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a5, 0x9d} /* sign */, + {0x00a7, 0xdd} /* sign */, + {0x00a8, 0xb9} /* diaeresis */, + {0x00a9, 0xbd} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ae, 0xbe} /* sign */, + {0x00af, 0xff} /* macron */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xfe} /* three */, + {0x00b4, 0xba} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0xbc} /* sign */, + {0x00b7, 0xfa} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0xb6} /* capital letter a with grave */, + {0x00c3, 0xb7} /* capital letter a with tilde */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d5, 0xb8} /* capital letter o with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d8, 0xb2} /* capital letter o with stroke */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0x9e} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0xb0} /* small letter a with tilde */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0xb1} /* small letter o with tilde */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0xb3} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0132, 0xc1} /* capital ligature ij */, + {0x0133, 0xc0} /* small ligature ij */, + {0x0152, 0xb5} /* capital ligature oe */, + {0x0153, 0xb4} /* small ligature oe */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b2, 0xe1} /* small letter beta */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b8, 0xe9} /* small letter theta */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x05d0, 0xc2} /* letter alef */, + {0x05d1, 0xc3} /* letter bet */, + {0x05d2, 0xc4} /* letter gimel */, + {0x05d3, 0xc5} /* letter dalet */, + {0x05d4, 0xc6} /* letter he */, + {0x05d5, 0xc7} /* letter vav */, + {0x05d6, 0xc8} /* letter zayin */, + {0x05d7, 0xc9} /* letter het */, + {0x05d8, 0xca} /* letter tet */, + {0x05d9, 0xcb} /* letter yod */, + {0x05da, 0xd9} /* letter final kaf */, + {0x05db, 0xcc} /* letter kaf */, + {0x05dc, 0xcd} /* letter lamed */, + {0x05dd, 0xda} /* letter final mem */, + {0x05de, 0xce} /* letter mem */, + {0x05df, 0xd8} /* letter final nun */, + {0x05e0, 0xcf} /* letter nun */, + {0x05e1, 0xd0} /* letter samekh */, + {0x05e2, 0xd1} /* letter ayin */, + {0x05e3, 0xdb} /* letter final pe */, + {0x05e4, 0xd2} /* letter pe */, + {0x05e5, 0xdc} /* letter final tsadi */, + {0x05e6, 0xd3} /* letter tsadi */, + {0x05e7, 0xd4} /* letter qof */, + {0x05e8, 0xd5} /* letter resh */, + {0x05e9, 0xd6} /* letter shin */, + {0x05ea, 0xd7} /* letter tav */, + {0x2020, 0xbb} /* dagger */, + {0x2022, 0xf9} /* puce */, + {0x2038, 0xde} /* caret */, + {0x207f, 0xfc} /* latin small letter n */, + {0x2122, 0xbf} /* mark sign */, + {0x2126, 0xea} /* sign */, + {0x2208, 0xee} /* of */, + {0x220f, 0xef} /* product */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xdf} /* infinity */, + {0x222e, 0xec} /* integral */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */ +}; + +/* +#define cet_ucs4_to_atarist_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_atarist_extra[cet_ucs4_to_atarist_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_atarist = /* defined in cet.h */ +{ + cet_cs_name_atarist, /* name of character set */ + cet_cs_alias_atarist, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_atarist, /* char to UCS-4 value table */ + cet_ucs4_ofs_atarist, /* first non standard character */ + cet_ucs4_cnt_atarist, /* number of values in table */ + + cet_ucs4_to_atarist_links, /* UCS-4 to char links */ + cet_ucs4_to_atarist_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int atarist_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x00df, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x00e3, 0x00f5, 0x00d8, 0x00f8, 0x0153, 0x0152, 0x00c0, 0x00c3, + 0x00d5, 0x00a8, 0x00b4, 0x2020, 0x00b6, 0x00a9, 0x00ae, 0x2122, + 0x0133, 0x0132, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, + 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05db, 0x05dc, 0x05de, 0x05e0, + 0x05e1, 0x05e2, 0x05e4, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, + 0x05df, 0x05da, 0x05dd, 0x05e3, 0x05e5, 0x00a7, 0x2038, 0x221e, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x03b8, 0x2126, 0x03b4, 0x222e, 0x03c6, 0x2208, 0x220f, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2022, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x00b3, 0x00af +}; +*/ + +#endif diff --git a/cet/baltic.h b/cet/baltic.h new file mode 100644 index 000000000..fdc436294 --- /dev/null +++ b/cet/baltic.h @@ -0,0 +1,178 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "baltic" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef baltic_h +#define baltic_h + +#define cet_cs_name_baltic "baltic" + +const char *cet_cs_alias_baltic[] = +{ + "baltic", "iso-ir-179", NULL +}; + +#define cet_ucs4_ofs_baltic 161 +#define cet_ucs4_cnt_baltic 95 + +const int cet_ucs4_map_baltic[cet_ucs4_cnt_baltic] = +{ + 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00d8, + 0x00a9, 0x201e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, 0x00b0, + 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00f8, + 0x00b9, 0x201c, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, 0x012e, + 0x0116, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0104, 0x010c, 0x0122, + 0x00c9, 0x017d, 0x0118, 0x0112, 0x0136, 0x012a, 0x013b, 0x0141, + 0x0145, 0x0143, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, + 0x0160, 0x015a, 0x016a, 0x00dc, 0x017b, 0x0179, 0x00df, 0x012f, + 0x0117, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0105, 0x010d, 0x0123, + 0x00e9, 0x017e, 0x0119, 0x0113, 0x0137, 0x012b, 0x013c, 0x0142, + 0x0146, 0x0144, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, + 0x0161, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017a, 0x0138 +}; + +#define cet_ucs4_to_baltic_ct 54 + +const cet_ucs4_link_t cet_ucs4_to_baltic_links[cet_ucs4_to_baltic_ct] = +{ + {0x00c6, 0xaf} /* capital letter ae */, + {0x00d8, 0xa8} /* capital letter o with stroke */, + {0x00e6, 0xbf} /* small letter ae */, + {0x00f8, 0xb8} /* small letter o with stroke */, + {0x0100, 0xc2} /* capital letter a with macron */, + {0x0101, 0xe2} /* small letter a with macron */, + {0x0104, 0xc6} /* capital letter a with ogonek */, + {0x0105, 0xe6} /* small letter a with ogonek */, + {0x0106, 0xc3} /* capital letter c with acute */, + {0x0107, 0xe3} /* small letter c with acute */, + {0x010c, 0xc7} /* capital letter c with caron */, + {0x010d, 0xe7} /* small letter c with caron */, + {0x0112, 0xcc} /* capital letter e with macron */, + {0x0113, 0xec} /* small letter e with macron */, + {0x0116, 0xc1} /* capital letter e with dot above */, + {0x0117, 0xe1} /* small letter e with dot above */, + {0x0118, 0xcb} /* capital letter e with ogonek */, + {0x0119, 0xeb} /* small letter e with ogonek */, + {0x0122, 0xc8} /* capital letter g with cedilla */, + {0x0123, 0xe8} /* small letter g with cedilla */, + {0x012a, 0xce} /* capital letter i with macron */, + {0x012b, 0xee} /* small letter i with macron */, + {0x012e, 0xc0} /* capital letter i with ogonek */, + {0x012f, 0xe0} /* small letter i with ogonek */, + {0x0136, 0xcd} /* capital letter k with cedilla */, + {0x0137, 0xed} /* small letter k with cedilla */, + {0x0138, 0xff} /* small letter kra (greenlandic) */, + {0x013b, 0xcf} /* capital letter l with cedilla */, + {0x013c, 0xef} /* small letter l with cedilla */, + {0x0141, 0xd0} /* capital letter l with stroke */, + {0x0142, 0xf0} /* small letter l with stroke */, + {0x0143, 0xd2} /* capital letter n with acute */, + {0x0144, 0xf2} /* small letter n with acute */, + {0x0145, 0xd1} /* capital letter n with cedilla */, + {0x0146, 0xf1} /* small letter n with cedilla */, + {0x014c, 0xd4} /* capital letter o with macron */, + {0x014d, 0xf4} /* small letter o with macron */, + {0x015a, 0xda} /* capital letter s with acute */, + {0x015b, 0xfa} /* small letter s with acute */, + {0x0160, 0xd9} /* capital letter s with caron */, + {0x0161, 0xf9} /* small letter s with caron */, + {0x016a, 0xdb} /* capital letter u with macron */, + {0x016b, 0xfb} /* small letter u with macron */, + {0x0172, 0xd8} /* capital letter u with ogonek */, + {0x0173, 0xf8} /* small letter u with ogonek */, + {0x0179, 0xde} /* capital letter z with acute */, + {0x017a, 0xfe} /* small letter z with acute */, + {0x017b, 0xdd} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xca} /* capital letter z with caron */, + {0x017e, 0xea} /* small letter z with caron */, + {0x201c, 0xba} /* double quotation mark */, + {0x201d, 0xa1} /* double quotation mark */, + {0x201e, 0xaa} /* low-9 quotation mark */ +}; + +/* +#define cet_ucs4_to_baltic_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_baltic_extra[cet_ucs4_to_baltic_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_baltic = /* defined in cet.h */ +{ + cet_cs_name_baltic, /* name of character set */ + cet_cs_alias_baltic, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_baltic, /* char to UCS-4 value table */ + cet_ucs4_ofs_baltic, /* first non standard character */ + cet_ucs4_cnt_baltic, /* number of values in table */ + + cet_ucs4_to_baltic_links, /* UCS-4 to char links */ + cet_ucs4_to_baltic_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int baltic_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x201e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x201c, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x012e, 0x0116, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0104, 0x010c, + 0x0122, 0x00c9, 0x017d, 0x0118, 0x0112, 0x0136, 0x012a, 0x013b, + 0x0141, 0x0145, 0x0143, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0160, 0x015a, 0x016a, 0x00dc, 0x017b, 0x0179, 0x00df, + 0x012f, 0x0117, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0105, 0x010d, + 0x0123, 0x00e9, 0x017e, 0x0119, 0x0113, 0x0137, 0x012b, 0x013c, + 0x0142, 0x0146, 0x0144, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0161, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017a, 0x0138 +}; +*/ + +#endif diff --git a/cet/bs_4730.h b/cet/bs_4730.h new file mode 100644 index 000000000..1aea8fecf --- /dev/null +++ b/cet/bs_4730.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "BS_4730" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef bs_4730_h +#define bs_4730_h + +#define cet_cs_name_bs_4730 "BS_4730" + +const char *cet_cs_alias_bs_4730[] = +{ + "BS_4730", "gb", "ISO646-GB", "iso-ir-4", + "uk", NULL +}; + +#define cet_ucs4_ofs_bs_4730 35 +#define cet_ucs4_cnt_bs_4730 93 + +const int cet_ucs4_map_bs_4730[cet_ucs4_cnt_bs_4730] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x007b, 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_bs_4730_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_bs_4730_links[cet_ucs4_to_bs_4730_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_bs_4730_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_bs_4730_extra[cet_ucs4_to_bs_4730_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_bs_4730 = /* defined in cet.h */ +{ + cet_cs_name_bs_4730, /* name of character set */ + cet_cs_alias_bs_4730, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_bs_4730, /* char to UCS-4 value table */ + cet_ucs4_ofs_bs_4730, /* first non standard character */ + cet_ucs4_cnt_bs_4730, /* number of values in table */ + + cet_ucs4_to_bs_4730_links, /* UCS-4 to char links */ + cet_ucs4_to_bs_4730_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int bs_4730_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/bs_viewdata.h b/cet/bs_viewdata.h new file mode 100644 index 000000000..b8f450f28 --- /dev/null +++ b/cet/bs_viewdata.h @@ -0,0 +1,134 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "BS_viewdata" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef bs_viewdata_h +#define bs_viewdata_h + +#define cet_cs_name_bs_viewdata "BS_viewdata" + +const char *cet_cs_alias_bs_viewdata[] = +{ + "BS_viewdata", "iso-ir-47", NULL +}; + +#define cet_ucs4_ofs_bs_viewdata 35 +#define cet_ucs4_cnt_bs_viewdata 93 + +const int cet_ucs4_map_bs_viewdata[cet_ucs4_cnt_bs_viewdata] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x2190, 0x00bd, 0x2192, 0x2191, 0x25a1, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00bc, 0x2225, 0x00be, 0x00f7, 0x007f +}; + +#define cet_ucs4_to_bs_viewdata_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_bs_viewdata_links[cet_ucs4_to_bs_viewdata_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00bc, 0x7b} /* fraction one quarter */, + {0x00bd, 0x5c} /* fraction one half */, + {0x00be, 0x7d} /* fraction three quarters */, + {0x00f7, 0x7e} /* sign */, + {0x2190, 0x5b} /* arrow */, + {0x2191, 0x5e} /* arrow */, + {0x2192, 0x5d} /* arrow */, + {0x2225, 0x7c} /* to */, + {0x25a1, 0x5f} /* square */ +}; + +/* +#define cet_ucs4_to_bs_viewdata_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_bs_viewdata_extra[cet_ucs4_to_bs_viewdata_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_bs_viewdata = /* defined in cet.h */ +{ + cet_cs_name_bs_viewdata, /* name of character set */ + cet_cs_alias_bs_viewdata, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_bs_viewdata, /* char to UCS-4 value table */ + cet_ucs4_ofs_bs_viewdata, /* first non standard character */ + cet_ucs4_cnt_bs_viewdata, /* number of values in table */ + + cet_ucs4_to_bs_viewdata_links, /* UCS-4 to char links */ + cet_ucs4_to_bs_viewdata_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int bs_viewdata_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x2190, 0x00bd, 0x2192, 0x2191, 0x25a1, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00bc, 0x2225, 0x00be, 0x00f7, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/cp1250.h b/cet/cp1250.h new file mode 100644 index 000000000..c16ba4d01 --- /dev/null +++ b/cet/cp1250.h @@ -0,0 +1,203 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1250" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1250_h +#define cp1250_h + +#define cet_cs_name_cp1250 "CP1250" + +const char *cet_cs_alias_cp1250[] = +{ + "CP1250", "1250", "ms-ee", "windows-1250", "WIN-CP1250", + NULL +}; + +#define cet_ucs4_ofs_cp1250 128 +#define cet_ucs4_cnt_cp1250 128 + +const int cet_ucs4_map_cp1250[cet_ucs4_cnt_cp1250] = +{ + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +#define cet_ucs4_to_cp1250_ct 74 + +const cet_ucs4_link_t cet_ucs4_to_cp1250_links[cet_ucs4_to_cp1250_ct] = +{ + {0x0102, 0xc3} /* capital letter a with breve */, + {0x0103, 0xe3} /* small letter a with breve */, + {0x0104, 0xa5} /* capital letter a with ogonek */, + {0x0105, 0xb9} /* small letter a with ogonek */, + {0x0106, 0xc6} /* capital letter c with acute */, + {0x0107, 0xe6} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x010e, 0xcf} /* capital letter d with caron */, + {0x010f, 0xef} /* small letter d with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011a, 0xcc} /* capital letter e with caron */, + {0x011b, 0xec} /* small letter e with caron */, + {0x0139, 0xc5} /* capital letter l with acute */, + {0x013a, 0xe5} /* small letter l with acute */, + {0x013d, 0xbc} /* capital letter l with caron */, + {0x013e, 0xbe} /* small letter l with caron */, + {0x0141, 0xa3} /* capital letter l with stroke */, + {0x0142, 0xb3} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0147, 0xd2} /* capital letter n with caron */, + {0x0148, 0xf2} /* small letter n with caron */, + {0x0150, 0xd5} /* capital letter o with double acute */, + {0x0151, 0xf5} /* small letter o with double acute */, + {0x0154, 0xc0} /* capital letter r with acute */, + {0x0155, 0xe0} /* small letter r with acute */, + {0x0158, 0xd8} /* capital letter r with caron */, + {0x0159, 0xf8} /* small letter r with caron */, + {0x015a, 0x8c} /* capital letter s with acute */, + {0x015b, 0x9c} /* small letter s with acute */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0162, 0xde} /* capital letter t with cedilla */, + {0x0163, 0xfe} /* small letter t with cedilla */, + {0x0164, 0x8d} /* capital letter t with caron */, + {0x0165, 0x9d} /* small letter t with caron */, + {0x016e, 0xd9} /* capital letter u with ring above */, + {0x016f, 0xf9} /* small letter u with ring above */, + {0x0170, 0xdb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0x8f} /* capital letter z with acute */, + {0x017a, 0x9f} /* small letter z with acute */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x017d, 0x8e} /* capital letter z with caron */, + {0x017e, 0x9e} /* small letter z with caron */, + {0x02c7, 0xa1} /* caron */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */, + {0x02dd, 0xbd} /* acute accent */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1250_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1250_extra[cet_ucs4_to_cp1250_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1250 = /* defined in cet.h */ +{ + cet_cs_name_cp1250, /* name of character set */ + cet_cs_alias_cp1250, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1250, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1250, /* first non standard character */ + cet_ucs4_cnt_cp1250, /* number of values in table */ + + cet_ucs4_to_cp1250_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1250_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1250_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; +*/ + +#endif diff --git a/cet/cp1251.h b/cet/cp1251.h new file mode 100644 index 000000000..efa2195c3 --- /dev/null +++ b/cet/cp1251.h @@ -0,0 +1,241 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1251" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1251_h +#define cp1251_h + +#define cet_cs_name_cp1251 "CP1251" + +const char *cet_cs_alias_cp1251[] = +{ + "CP1251", "1251", "ms-cyrl", "windows-1251", "WIN-CP1251", + NULL +}; + +#define cet_ucs4_ofs_cp1251 128 +#define cet_ucs4_cnt_cp1251 128 + +const int cet_ucs4_map_cp1251[cet_ucs4_cnt_cp1251] = +{ + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f +}; + +#define cet_ucs4_to_cp1251_ct 112 + +const cet_ucs4_link_t cet_ucs4_to_cp1251_links[cet_ucs4_to_cp1251_ct] = +{ + {0x0401, 0xa8} /* capital letter io */, + {0x0402, 0x80} /* capital letter dje (serbocroatian) */, + {0x0403, 0x81} /* capital letter gje (macedonian) */, + {0x0404, 0xaa} /* capital letter ukrainian ie */, + {0x0405, 0xbd} /* capital letter dze (macedonian) */, + {0x0406, 0xb2} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xaf} /* capital letter yi (ukrainian) */, + {0x0408, 0xa3} /* capital letter je */, + {0x0409, 0x8a} /* capital letter lje */, + {0x040a, 0x8c} /* capital letter nje */, + {0x040b, 0x8e} /* capital letter tshe (serbocroatian) */, + {0x040c, 0x8d} /* capital letter kje (macedonian) */, + {0x040e, 0xa1} /* capital letter short u (byelorussian) */, + {0x040f, 0x8f} /* capital letter dzhe */, + {0x0410, 0xc0} /* capital letter a */, + {0x0411, 0xc1} /* capital letter be */, + {0x0412, 0xc2} /* capital letter ve */, + {0x0413, 0xc3} /* capital letter ghe */, + {0x0414, 0xc4} /* capital letter de */, + {0x0415, 0xc5} /* capital letter ie */, + {0x0416, 0xc6} /* capital letter zhe */, + {0x0417, 0xc7} /* capital letter ze */, + {0x0418, 0xc8} /* capital letter i */, + {0x0419, 0xc9} /* capital letter short i */, + {0x041a, 0xca} /* capital letter ka */, + {0x041b, 0xcb} /* capital letter el */, + {0x041c, 0xcc} /* capital letter em */, + {0x041d, 0xcd} /* capital letter en */, + {0x041e, 0xce} /* capital letter o */, + {0x041f, 0xcf} /* capital letter pe */, + {0x0420, 0xd0} /* capital letter er */, + {0x0421, 0xd1} /* capital letter es */, + {0x0422, 0xd2} /* capital letter te */, + {0x0423, 0xd3} /* capital letter u */, + {0x0424, 0xd4} /* capital letter ef */, + {0x0425, 0xd5} /* capital letter ha */, + {0x0426, 0xd6} /* capital letter tse */, + {0x0427, 0xd7} /* capital letter che */, + {0x0428, 0xd8} /* capital letter sha */, + {0x0429, 0xd9} /* capital letter shcha */, + {0x042a, 0xda} /* capital letter hard sign */, + {0x042b, 0xdb} /* capital letter yeru */, + {0x042c, 0xdc} /* capital letter soft sign */, + {0x042d, 0xdd} /* capital letter e */, + {0x042e, 0xde} /* capital letter yu */, + {0x042f, 0xdf} /* capital letter ya */, + {0x0430, 0xe0} /* small letter a */, + {0x0431, 0xe1} /* small letter be */, + {0x0432, 0xe2} /* small letter ve */, + {0x0433, 0xe3} /* small letter ghe */, + {0x0434, 0xe4} /* small letter de */, + {0x0435, 0xe5} /* small letter ie */, + {0x0436, 0xe6} /* small letter zhe */, + {0x0437, 0xe7} /* small letter ze */, + {0x0438, 0xe8} /* small letter i */, + {0x0439, 0xe9} /* small letter short i */, + {0x043a, 0xea} /* small letter ka */, + {0x043b, 0xeb} /* small letter el */, + {0x043c, 0xec} /* small letter em */, + {0x043d, 0xed} /* small letter en */, + {0x043e, 0xee} /* small letter o */, + {0x043f, 0xef} /* small letter pe */, + {0x0440, 0xf0} /* small letter er */, + {0x0441, 0xf1} /* small letter es */, + {0x0442, 0xf2} /* small letter te */, + {0x0443, 0xf3} /* small letter u */, + {0x0444, 0xf4} /* small letter ef */, + {0x0445, 0xf5} /* small letter ha */, + {0x0446, 0xf6} /* small letter tse */, + {0x0447, 0xf7} /* small letter che */, + {0x0448, 0xf8} /* small letter sha */, + {0x0449, 0xf9} /* small letter shcha */, + {0x044a, 0xfa} /* small letter hard sign */, + {0x044b, 0xfb} /* small letter yeru */, + {0x044c, 0xfc} /* small letter soft sign */, + {0x044d, 0xfd} /* small letter e */, + {0x044e, 0xfe} /* small letter yu */, + {0x044f, 0xff} /* small letter ya */, + {0x0451, 0xb8} /* small letter io */, + {0x0452, 0x90} /* small letter dje (serbocroatian) */, + {0x0453, 0x83} /* small letter gje (macedonian) */, + {0x0454, 0xba} /* small letter ukrainian ie */, + {0x0455, 0xbe} /* small letter dze (macedonian) */, + {0x0456, 0xb3} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xbf} /* small letter yi (ukrainian) */, + {0x0458, 0xbc} /* small letter je */, + {0x0459, 0x9a} /* small letter lje */, + {0x045a, 0x9c} /* small letter nje */, + {0x045b, 0x9e} /* small letter tshe (serbocroatian) */, + {0x045c, 0x9d} /* small letter kje (macedonian) */, + {0x045e, 0xa2} /* small letter short u (byelorussian) */, + {0x045f, 0x9f} /* small letter dzhe */, + {0x0490, 0xa5} /* capital letter ghe with upturn */, + {0x0491, 0xb4} /* small letter ghe with upturn */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x88} /* euro */, + {0x2116, 0xb9} /* sign */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1251_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1251_extra[cet_ucs4_to_cp1251_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1251 = /* defined in cet.h */ +{ + cet_cs_name_cp1251, /* name of character set */ + cet_cs_alias_cp1251, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1251, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1251, /* first non standard character */ + cet_ucs4_cnt_cp1251, /* number of values in table */ + + cet_ucs4_to_cp1251_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1251_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1251_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f +}; +*/ + +#endif diff --git a/cet/cp1252.h b/cet/cp1252.h new file mode 100644 index 000000000..01f202325 --- /dev/null +++ b/cet/cp1252.h @@ -0,0 +1,156 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1252" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1252_h +#define cp1252_h + +#define cet_cs_name_cp1252 "CP1252" + +const char *cet_cs_alias_cp1252[] = +{ + "CP1252", "1252", "ms-ansi", "windows-1252", "WIN-CP1252", + NULL +}; + +#define cet_ucs4_ofs_cp1252 128 +#define cet_ucs4_cnt_cp1252 128 + +const int cet_ucs4_map_cp1252[cet_ucs4_cnt_cp1252] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, 0x017d, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, 0x017e, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_cp1252_ct 27 + +const cet_ucs4_link_t cet_ucs4_to_cp1252_links[cet_ucs4_to_cp1252_ct] = +{ + {0x0152, 0x8c} /* capital ligature oe */, + {0x0153, 0x9c} /* small ligature oe */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x017d, 0x8e} /* capital letter z with caron */, + {0x017e, 0x9e} /* small letter z with caron */, + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x02c6, 0x88} /* modificative accent circonflexe */, + {0x02dc, 0x98} /* tilde */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1252_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1252_extra[cet_ucs4_to_cp1252_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1252 = /* defined in cet.h */ +{ + cet_cs_name_cp1252, /* name of character set */ + cet_cs_alias_cp1252, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1252, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1252, /* first non standard character */ + cet_ucs4_cnt_cp1252, /* number of values in table */ + + cet_ucs4_to_cp1252_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1252_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1252_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, 0x017d, 0x017e, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/cp1253.h b/cet/cp1253.h new file mode 100644 index 000000000..727139847 --- /dev/null +++ b/cet/cp1253.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1253" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1253_h +#define cp1253_h + +#define cet_cs_name_cp1253 "CP1253" + +const char *cet_cs_alias_cp1253[] = +{ + "CP1253", "1253", "ms-greek", "windows-1253", "WIN-CP1253", + NULL +}; + +#define cet_ucs4_ofs_cp1253 128 +#define cet_ucs4_cnt_cp1253 127 + +const int cet_ucs4_map_cp1253[cet_ucs4_cnt_cp1253] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce +}; + +#define cet_ucs4_to_cp1253_ct 90 + +const cet_ucs4_link_t cet_ucs4_to_cp1253_links[cet_ucs4_to_cp1253_ct] = +{ + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x0384, 0xb4} /* grec tonos */, + {0x0385, 0xa1} /* accent and diaeresis (tonos and dialytika) */, + {0x0386, 0xa2} /* capital letter alpha with acute */, + {0x0388, 0xb8} /* capital letter epsilon with acute */, + {0x0389, 0xb9} /* capital letter eta with acute */, + {0x038a, 0xba} /* capital letter iota with acute */, + {0x038c, 0xbc} /* capital letter omicron with acute */, + {0x038e, 0xbe} /* capital letter upsilon with acute */, + {0x038f, 0xbf} /* capital letter omega with acute */, + {0x0390, 0xc0} /* small letter iota with acute and diaeresis */, + {0x0391, 0xc1} /* capital letter alpha */, + {0x0392, 0xc2} /* capital letter beta */, + {0x0393, 0xc3} /* capital letter gamma */, + {0x0394, 0xc4} /* capital letter delta */, + {0x0395, 0xc5} /* capital letter epsilon */, + {0x0396, 0xc6} /* capital letter zeta */, + {0x0397, 0xc7} /* capital letter eta */, + {0x0398, 0xc8} /* capital letter theta */, + {0x0399, 0xc9} /* capital letter iota */, + {0x039a, 0xca} /* capital letter kappa */, + {0x039b, 0xcb} /* capital letter lamda */, + {0x039c, 0xcc} /* capital letter mu */, + {0x039d, 0xcd} /* capital letter nu */, + {0x039e, 0xce} /* capital letter xi */, + {0x039f, 0xcf} /* capital letter omicron */, + {0x03a0, 0xd0} /* capital letter pi */, + {0x03a1, 0xd1} /* capital letter rho */, + {0x03a3, 0xd3} /* capital letter sigma */, + {0x03a4, 0xd4} /* capital letter tau */, + {0x03a5, 0xd5} /* capital letter upsilon */, + {0x03a6, 0xd6} /* capital letter phi */, + {0x03a7, 0xd7} /* capital letter chi */, + {0x03a8, 0xd8} /* capital letter psi */, + {0x03a9, 0xd9} /* capital letter omega */, + {0x03aa, 0xda} /* capital letter iota with diaeresis */, + {0x03ab, 0xdb} /* capital letter upsilon with diaeresis */, + {0x03ac, 0xdc} /* small letter alpha with acute */, + {0x03ad, 0xdd} /* small letter epsilon with acute */, + {0x03ae, 0xde} /* small letter eta with acute */, + {0x03af, 0xdf} /* small letter iota with acute */, + {0x03b0, 0xe0} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xe1} /* small letter alpha */, + {0x03b2, 0xe2} /* small letter beta */, + {0x03b3, 0xe3} /* small letter gamma */, + {0x03b4, 0xe4} /* small letter delta */, + {0x03b5, 0xe5} /* small letter epsilon */, + {0x03b6, 0xe6} /* small letter zeta */, + {0x03b7, 0xe7} /* small letter eta */, + {0x03b8, 0xe8} /* small letter theta */, + {0x03b9, 0xe9} /* small letter iota */, + {0x03ba, 0xea} /* small letter kappa */, + {0x03bb, 0xeb} /* small letter lamda */, + {0x03bc, 0xec} /* small letter mu */, + {0x03bd, 0xed} /* small letter nu */, + {0x03be, 0xee} /* small letter xi */, + {0x03bf, 0xef} /* small letter omicron */, + {0x03c0, 0xf0} /* small letter pi */, + {0x03c1, 0xf1} /* small letter rho */, + {0x03c2, 0xf2} /* small letter final sigma */, + {0x03c3, 0xf3} /* small letter sigma */, + {0x03c4, 0xf4} /* small letter tau */, + {0x03c5, 0xf5} /* small letter upsilon */, + {0x03c6, 0xf6} /* small letter phi */, + {0x03c7, 0xf7} /* small letter chi */, + {0x03c8, 0xf8} /* small letter psi */, + {0x03c9, 0xf9} /* small letter omega */, + {0x03ca, 0xfa} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xfc} /* small letter omicron with acute */, + {0x03cd, 0xfd} /* small letter upsilon with acute */, + {0x03ce, 0xfe} /* small letter omega with acute */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2015, 0xaf} /* bar */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1253_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1253_extra[cet_ucs4_to_cp1253_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1253 = /* defined in cet.h */ +{ + cet_cs_name_cp1253, /* name of character set */ + cet_cs_alias_cp1253, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1253, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1253, /* first non standard character */ + cet_ucs4_cnt_cp1253, /* number of values in table */ + + cet_ucs4_to_cp1253_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1253_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1253_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, -1 +}; +*/ + +#endif diff --git a/cet/cp1254.h b/cet/cp1254.h new file mode 100644 index 000000000..55b75b6db --- /dev/null +++ b/cet/cp1254.h @@ -0,0 +1,163 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1254" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1254_h +#define cp1254_h + +#define cet_cs_name_cp1254 "CP1254" + +const char *cet_cs_alias_cp1254[] = +{ + "CP1254", "1254", "ms-turk", "windows-1254", "WIN-CP1254", + NULL +}; + +#define cet_ucs4_ofs_cp1254 128 +#define cet_ucs4_cnt_cp1254 128 + +const int cet_ucs4_map_cp1254[cet_ucs4_cnt_cp1254] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; + +#define cet_ucs4_to_cp1254_ct 34 + +const cet_ucs4_link_t cet_ucs4_to_cp1254_links[cet_ucs4_to_cp1254_ct] = +{ + {0x0117, 0xec} /* small letter e with dot above */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011e, 0xd0} /* capital letter g with breve */, + {0x011f, 0xf0} /* small letter g with breve */, + {0x012b, 0xef} /* small letter i with macron */, + {0x0130, 0xdd} /* capital letter i with dot above */, + {0x0131, 0xfd} /* small letter i dotless */, + {0x0152, 0x8c} /* capital ligature oe */, + {0x0153, 0x9c} /* small ligature oe */, + {0x015e, 0xde} /* capital letter s with cedilla */, + {0x015f, 0xfe} /* small letter s with cedilla */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x02c6, 0x88} /* modificative accent circonflexe */, + {0x02dc, 0x98} /* tilde */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1254_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1254_extra[cet_ucs4_to_cp1254_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1254 = /* defined in cet.h */ +{ + cet_cs_name_cp1254, /* name of character set */ + cet_cs_alias_cp1254, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1254, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1254, /* first non standard character */ + cet_ucs4_cnt_cp1254, /* number of values in table */ + + cet_ucs4_to_cp1254_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1254_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1254_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; +*/ + +#endif diff --git a/cet/cp1255.h b/cet/cp1255.h new file mode 100644 index 000000000..d80498da3 --- /dev/null +++ b/cet/cp1255.h @@ -0,0 +1,180 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1255" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1255_h +#define cp1255_h + +#define cet_cs_name_cp1255 "CP1255" + +const char *cet_cs_alias_cp1255[] = +{ + "CP1255", "1255", "ms-hebr", "windows-1255", "WIN-CP1255", + NULL +}; + +#define cet_ucs4_ofs_cp1255 128 +#define cet_ucs4_cnt_cp1255 127 + +const int cet_ucs4_map_cp1255[cet_ucs4_cnt_cp1255] = +{ + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, -1, -1, 0x200e, 0x200f +}; + +#define cet_ucs4_to_cp1255_ct 51 + +const cet_ucs4_link_t cet_ucs4_to_cp1255_links[cet_ucs4_to_cp1255_ct] = +{ + {0x00d7, 0xaa} /* sign */, + {0x00f7, 0xba} /* sign */, + {0x0192, 0x83} /* minuscule latine f hameçon */, + {0x05d0, 0xe0} /* letter alef */, + {0x05d1, 0xe1} /* letter bet */, + {0x05d2, 0xe2} /* letter gimel */, + {0x05d3, 0xe3} /* letter dalet */, + {0x05d4, 0xe4} /* letter he */, + {0x05d5, 0xe5} /* letter vav */, + {0x05d6, 0xe6} /* letter zayin */, + {0x05d7, 0xe7} /* letter het */, + {0x05d8, 0xe8} /* letter tet */, + {0x05d9, 0xe9} /* letter yod */, + {0x05da, 0xea} /* letter final kaf */, + {0x05db, 0xeb} /* letter kaf */, + {0x05dc, 0xec} /* letter lamed */, + {0x05dd, 0xed} /* letter final mem */, + {0x05de, 0xee} /* letter mem */, + {0x05df, 0xef} /* letter final nun */, + {0x05e0, 0xf0} /* letter nun */, + {0x05e1, 0xf1} /* letter samekh */, + {0x05e2, 0xf2} /* letter ayin */, + {0x05e3, 0xf3} /* letter final pe */, + {0x05e4, 0xf4} /* letter pe */, + {0x05e5, 0xf5} /* letter final tsadi */, + {0x05e6, 0xf6} /* letter tsadi */, + {0x05e7, 0xf7} /* letter qof */, + {0x05e8, 0xf8} /* letter resh */, + {0x05e9, 0xf9} /* letter shin */, + {0x05ea, 0xfa} /* letter tav */, + {0x200e, 0xfd} /* gauche-à-droite */, + {0x200f, 0xfe} /* droite-à-gauche */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2017, 0xdf} /* low line */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x203e, 0xaf} /* overline */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1255_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1255_extra[cet_ucs4_to_cp1255_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1255 = /* defined in cet.h */ +{ + cet_cs_name_cp1255, /* name of character set */ + cet_cs_alias_cp1255, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1255, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1255, /* first non standard character */ + cet_ucs4_cnt_cp1255, /* number of values in table */ + + cet_ucs4_to_cp1255_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1255_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1255_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, -1, -1, 0x200e, 0x200f, -1 +}; +*/ + +#endif diff --git a/cet/cp1256.h b/cet/cp1256.h new file mode 100644 index 000000000..b4d8941c5 --- /dev/null +++ b/cet/cp1256.h @@ -0,0 +1,210 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1256" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1256_h +#define cp1256_h + +#define cet_cs_name_cp1256 "CP1256" + +const char *cet_cs_alias_cp1256[] = +{ + "CP1256", "1256", "ms-arab", "windows-1256", "WIN-CP1256", + NULL +}; + +#define cet_ucs4_ofs_cp1256 128 +#define cet_ucs4_cnt_cp1256 128 + +const int cet_ucs4_map_cp1256[cet_ucs4_cnt_cp1256] = +{ + 0x20ac, 0x0660, 0x201a, 0x0661, 0x201e, 0x2026, 0x2020, 0x2021, + 0x0662, 0x0663, 0x0664, 0x2039, 0x0665, 0x0666, 0x0667, 0x0668, + 0x0669, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x061b, 0x2122, 0x061f, 0x203a, 0x0621, 0x0622, 0x0623, 0x0178, + 0x00a0, 0x0624, 0x0625, 0x00a3, 0x00a4, 0x0626, 0x00a6, 0x00a7, + 0x0627, 0x00a9, 0x0628, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x067e, + 0x00b0, 0x00b1, 0x0629, 0x062a, 0x062b, 0x00b5, 0x00b6, 0x00b7, + 0x062c, 0x0686, 0x062d, 0x00bb, 0x062e, 0x062f, 0x0630, 0x0631, + 0x00c0, 0x0632, 0x00c2, 0x0698, 0x0633, 0x0634, 0x0635, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0636, 0x0637, 0x00ce, 0x00cf, + 0x3113, 0x0639, 0x063a, 0x0640, 0x00d4, 0x0641, 0x0642, 0x00d7, + 0x0643, 0x00d9, 0x06af, 0x00db, 0x00dc, 0x0644, 0x0645, 0x0646, + 0x00e0, 0x0647, 0x00e2, 0x0681, 0x0648, 0x0649, 0x064a, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x064b, 0x064c, 0x00ee, 0x00ef, + 0x064d, 0x064e, 0x064f, 0x0650, 0x00f4, 0x0651, 0x0652, 0x00f7, + -1, 0x00f9, -1, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x00ff +}; + +#define cet_ucs4_to_cp1256_ct 81 + +const cet_ucs4_link_t cet_ucs4_to_cp1256_links[cet_ucs4_to_cp1256_ct] = +{ + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x061b, 0x98} /* semicolon */, + {0x061f, 0x9a} /* question mark */, + {0x0621, 0x9c} /* letter hamza */, + {0x0622, 0x9d} /* letter alef with madda above */, + {0x0623, 0x9e} /* letter alef with hamza above */, + {0x0624, 0xa1} /* letter waw with hamza above */, + {0x0625, 0xa2} /* letter alef with hamza below */, + {0x0626, 0xa5} /* letter yeh with hamza above */, + {0x0627, 0xa8} /* letter alef */, + {0x0628, 0xaa} /* letter beh */, + {0x0629, 0xb2} /* letter teh marbuta */, + {0x062a, 0xb3} /* letter teh */, + {0x062b, 0xb4} /* letter theh */, + {0x062c, 0xb8} /* letter jeem */, + {0x062d, 0xba} /* letter hah */, + {0x062e, 0xbc} /* letter khah */, + {0x062f, 0xbd} /* letter dal */, + {0x0630, 0xbe} /* letter thal */, + {0x0631, 0xbf} /* letter reh */, + {0x0632, 0xc1} /* letter zain */, + {0x0633, 0xc4} /* letter seen */, + {0x0634, 0xc5} /* letter sheen */, + {0x0635, 0xc6} /* letter sad */, + {0x0636, 0xcc} /* letter dad */, + {0x0637, 0xcd} /* letter tah */, + {0x0639, 0xd1} /* letter ain */, + {0x063a, 0xd2} /* letter ghain */, + {0x0640, 0xd3} /* tatweel */, + {0x0641, 0xd5} /* letter feh */, + {0x0642, 0xd6} /* letter qaf */, + {0x0643, 0xd8} /* letter kaf */, + {0x0644, 0xdd} /* letter lam */, + {0x0645, 0xde} /* letter meem */, + {0x0646, 0xdf} /* letter noon */, + {0x0647, 0xe1} /* letter heh */, + {0x0648, 0xe4} /* letter waw */, + {0x0649, 0xe5} /* letter alef maksura */, + {0x064a, 0xe6} /* letter yeh */, + {0x064b, 0xec} /* fathatan */, + {0x064c, 0xed} /* dammatan */, + {0x064d, 0xf0} /* kasratan */, + {0x064e, 0xf1} /* fatha */, + {0x064f, 0xf2} /* damma */, + {0x0650, 0xf3} /* kasra */, + {0x0651, 0xf5} /* shadda */, + {0x0652, 0xf6} /* sukun */, + {0x0660, 0x81} /* arabic-indic digit zero */, + {0x0661, 0x83} /* arabic-indic digit one */, + {0x0662, 0x88} /* arabic-indic digit two */, + {0x0663, 0x89} /* arabic-indic digit three */, + {0x0664, 0x8a} /* arabic-indic digit four */, + {0x0665, 0x8c} /* arabic-indic digit five */, + {0x0666, 0x8d} /* arabic-indic digit six */, + {0x0667, 0x8e} /* arabic-indic digit seven */, + {0x0668, 0x8f} /* arabic-indic digit eight */, + {0x0669, 0x90} /* arabic-indic digit nine */, + {0x067e, 0xaf} /* letter peh */, + {0x0681, 0xe3} /* arabe ha' hamza en chef */, + {0x0686, 0xb9} /* arabe tchim' */, + {0x0698, 0xc3} /* arabe ja' */, + {0x06af, 0xda} /* letter gaf */, + {0x200e, 0xfd} /* gauche-à-droite */, + {0x200f, 0xfe} /* droite-à-gauche */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */, + {0x3113, 0xd0} /* letter zh */ +}; + +/* +#define cet_ucs4_to_cp1256_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1256_extra[cet_ucs4_to_cp1256_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1256 = /* defined in cet.h */ +{ + cet_cs_name_cp1256, /* name of character set */ + cet_cs_alias_cp1256, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1256, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1256, /* first non standard character */ + cet_ucs4_cnt_cp1256, /* number of values in table */ + + cet_ucs4_to_cp1256_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1256_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1256_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, 0x0660, 0x201a, 0x0661, 0x201e, 0x2026, 0x2020, 0x2021, + 0x0662, 0x0663, 0x0664, 0x2039, 0x0665, 0x0666, 0x0667, 0x0668, + 0x0669, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x061b, 0x2122, 0x061f, 0x203a, 0x0621, 0x0622, 0x0623, 0x0178, + 0x00a0, 0x0624, 0x0625, 0x00a3, 0x00a4, 0x0626, 0x00a6, 0x00a7, + 0x0627, 0x00a9, 0x0628, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x067e, + 0x00b0, 0x00b1, 0x0629, 0x062a, 0x062b, 0x00b5, 0x00b6, 0x00b7, + 0x062c, 0x0686, 0x062d, 0x00bb, 0x062e, 0x062f, 0x0630, 0x0631, + 0x00c0, 0x0632, 0x00c2, 0x0698, 0x0633, 0x0634, 0x0635, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0636, 0x0637, 0x00ce, 0x00cf, + 0x3113, 0x0639, 0x063a, 0x0640, 0x00d4, 0x0641, 0x0642, 0x00d7, + 0x0643, 0x00d9, 0x06af, 0x00db, 0x00dc, 0x0644, 0x0645, 0x0646, + 0x00e0, 0x0647, 0x00e2, 0x0681, 0x0648, 0x0649, 0x064a, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x064b, 0x064c, 0x00ee, 0x00ef, + 0x064d, 0x064e, 0x064f, 0x0650, 0x00f4, 0x0651, 0x0652, 0x00f7, + -1, 0x00f9, -1, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x00ff +}; +*/ + +#endif diff --git a/cet/cp1257.h b/cet/cp1257.h new file mode 100644 index 000000000..3e9355fd1 --- /dev/null +++ b/cet/cp1257.h @@ -0,0 +1,198 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CP1257" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cp1257_h +#define cp1257_h + +#define cet_cs_name_cp1257 "CP1257" + +const char *cet_cs_alias_cp1257[] = +{ + "CP1257", "1257", "WinBaltRim", "windows-1257", "WIN-CP1257", + NULL +}; + +#define cet_ucs4_ofs_cp1257 128 +#define cet_ucs4_cnt_cp1257 127 + +const int cet_ucs4_map_cp1257[cet_ucs4_cnt_cp1257] = +{ + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, -1, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e +}; + +#define cet_ucs4_to_cp1257_ct 69 + +const cet_ucs4_link_t cet_ucs4_to_cp1257_links[cet_ucs4_to_cp1257_ct] = +{ + {0x00c6, 0xaf} /* capital letter ae */, + {0x00d8, 0xa8} /* capital letter o with stroke */, + {0x00e6, 0xbf} /* small letter ae */, + {0x00f8, 0xb8} /* small letter o with stroke */, + {0x0100, 0xc2} /* capital letter a with macron */, + {0x0101, 0xe2} /* small letter a with macron */, + {0x0104, 0xc0} /* capital letter a with ogonek */, + {0x0105, 0xe0} /* small letter a with ogonek */, + {0x0106, 0xc3} /* capital letter c with acute */, + {0x0107, 0xe3} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0112, 0xc7} /* capital letter e with macron */, + {0x0113, 0xe7} /* small letter e with macron */, + {0x0116, 0xcb} /* capital letter e with dot above */, + {0x0117, 0xeb} /* small letter e with dot above */, + {0x0118, 0xc6} /* capital letter e with ogonek */, + {0x0119, 0xe6} /* small letter e with ogonek */, + {0x0122, 0xcc} /* capital letter g with cedilla */, + {0x0123, 0xec} /* small letter g with cedilla */, + {0x012a, 0xce} /* capital letter i with macron */, + {0x012b, 0xee} /* small letter i with macron */, + {0x012e, 0xc1} /* capital letter i with ogonek */, + {0x012f, 0xe1} /* small letter i with ogonek */, + {0x0136, 0xcd} /* capital letter k with cedilla */, + {0x0137, 0xed} /* small letter k with cedilla */, + {0x013b, 0xcf} /* capital letter l with cedilla */, + {0x013c, 0xef} /* small letter l with cedilla */, + {0x0141, 0xd9} /* capital letter l with stroke */, + {0x0142, 0xf9} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0145, 0xd2} /* capital letter n with cedilla */, + {0x0146, 0xf2} /* small letter n with cedilla */, + {0x014c, 0xd4} /* capital letter o with macron */, + {0x014d, 0xf4} /* small letter o with macron */, + {0x0156, 0xaa} /* capital letter r with cedilla */, + {0x0157, 0xba} /* small letter r with cedilla */, + {0x015a, 0xda} /* capital letter s with acute */, + {0x015b, 0xfa} /* small letter s with acute */, + {0x0160, 0xd0} /* capital letter s with caron */, + {0x0161, 0xf0} /* small letter s with caron */, + {0x016a, 0xdb} /* capital letter u with macron */, + {0x016b, 0xfb} /* small letter u with macron */, + {0x0172, 0xd8} /* capital letter u with ogonek */, + {0x0173, 0xf8} /* small letter u with ogonek */, + {0x0179, 0xca} /* capital letter z with acute */, + {0x017a, 0xea} /* small letter z with acute */, + {0x017b, 0xdd} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xde} /* capital letter z with caron */, + {0x017e, 0xfe} /* small letter z with caron */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x20ac, 0x80} /* euro */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_cp1257_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cp1257_extra[cet_ucs4_to_cp1257_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cp1257 = /* defined in cet.h */ +{ + cet_cs_name_cp1257, /* name of character set */ + cet_cs_alias_cp1257, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cp1257, /* char to UCS-4 value table */ + cet_ucs4_ofs_cp1257, /* first non standard character */ + cet_ucs4_cnt_cp1257, /* number of values in table */ + + cet_ucs4_to_cp1257_links, /* UCS-4 to char links */ + cet_ucs4_to_cp1257_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cp1257_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x20ac, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + -1, 0x2030, -1, 0x2039, -1, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + -1, 0x2122, -1, 0x203a, -1, -1, -1, -1, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, -1, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, -1 +}; +*/ + +#endif diff --git a/cet/csa_z243_4_1985_1.h b/cet/csa_z243_4_1985_1.h new file mode 100644 index 000000000..9c24e5cea --- /dev/null +++ b/cet/csa_z243_4_1985_1.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSA_Z243.4-1985-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csa_z243_4_1985_1_h +#define csa_z243_4_1985_1_h + +#define cet_cs_name_csa_z243_4_1985_1 "CSA_Z243.4-1985-1" + +const char *cet_cs_alias_csa_z243_4_1985_1[] = +{ + "CSA_Z243.4-1985-1", "ca", "csa7-1", "ISO646-CA", + "iso-ir-121", NULL +}; + +#define cet_ucs4_ofs_csa_z243_4_1985_1 64 +#define cet_ucs4_cnt_csa_z243_4_1985_1 64 + +const int cet_ucs4_map_csa_z243_4_1985_1[cet_ucs4_cnt_csa_z243_4_1985_1] = +{ + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00ee, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f +}; + +#define cet_ucs4_to_csa_z243_4_1985_1_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_1_links[cet_ucs4_to_csa_z243_4_1985_1_ct] = +{ + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e2, 0x5b} /* small letter a with circumflex */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00ea, 0x5d} /* small letter e with circumflex */, + {0x00ee, 0x5e} /* small letter i with circumflex */, + {0x00f4, 0x60} /* small letter o with circumflex */, + {0x00f9, 0x7c} /* small letter u with grave */, + {0x00fb, 0x7e} /* small letter u with circumflex */ +}; + +/* +#define cet_ucs4_to_csa_z243_4_1985_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_1_extra[cet_ucs4_to_csa_z243_4_1985_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csa_z243_4_1985_1 = /* defined in cet.h */ +{ + cet_cs_name_csa_z243_4_1985_1, /* name of character set */ + cet_cs_alias_csa_z243_4_1985_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csa_z243_4_1985_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_csa_z243_4_1985_1, /* first non standard character */ + cet_ucs4_cnt_csa_z243_4_1985_1, /* number of values in table */ + + cet_ucs4_to_csa_z243_4_1985_1_links, /* UCS-4 to char links */ + cet_ucs4_to_csa_z243_4_1985_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csa_z243_4_1985_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00ee, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/csa_z243_4_1985_2.h b/cet/csa_z243_4_1985_2.h new file mode 100644 index 000000000..0d5e54bea --- /dev/null +++ b/cet/csa_z243_4_1985_2.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSA_Z243.4-1985-2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csa_z243_4_1985_2_h +#define csa_z243_4_1985_2_h + +#define cet_cs_name_csa_z243_4_1985_2 "CSA_Z243.4-1985-2" + +const char *cet_cs_alias_csa_z243_4_1985_2[] = +{ + "CSA_Z243.4-1985-2", "csa7-2", "ISO646-CA2", "iso-ir-122", + NULL +}; + +#define cet_ucs4_ofs_csa_z243_4_1985_2 64 +#define cet_ucs4_cnt_csa_z243_4_1985_2 64 + +const int cet_ucs4_map_csa_z243_4_1985_2[cet_ucs4_cnt_csa_z243_4_1985_2] = +{ + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00c9, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f +}; + +#define cet_ucs4_to_csa_z243_4_1985_2_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_2_links[cet_ucs4_to_csa_z243_4_1985_2_ct] = +{ + {0x00c9, 0x5e} /* capital letter e with acute */, + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e2, 0x5b} /* small letter a with circumflex */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00ea, 0x5d} /* small letter e with circumflex */, + {0x00f4, 0x60} /* small letter o with circumflex */, + {0x00f9, 0x7c} /* small letter u with grave */, + {0x00fb, 0x7e} /* small letter u with circumflex */ +}; + +/* +#define cet_ucs4_to_csa_z243_4_1985_2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_2_extra[cet_ucs4_to_csa_z243_4_1985_2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csa_z243_4_1985_2 = /* defined in cet.h */ +{ + cet_cs_name_csa_z243_4_1985_2, /* name of character set */ + cet_cs_alias_csa_z243_4_1985_2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csa_z243_4_1985_2, /* char to UCS-4 value table */ + cet_ucs4_ofs_csa_z243_4_1985_2, /* first non standard character */ + cet_ucs4_cnt_csa_z243_4_1985_2, /* number of values in table */ + + cet_ucs4_to_csa_z243_4_1985_2_links, /* UCS-4 to char links */ + cet_ucs4_to_csa_z243_4_1985_2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csa_z243_4_1985_2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00e2, 0x00e7, 0x00ea, 0x00c9, 0x005f, + 0x00f4, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00fb, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/csa_z243_4_1985_gr.h b/cet/csa_z243_4_1985_gr.h new file mode 100644 index 000000000..32bd6053f --- /dev/null +++ b/cet/csa_z243_4_1985_gr.h @@ -0,0 +1,206 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSA_Z243.4-1985-gr" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csa_z243_4_1985_gr_h +#define csa_z243_4_1985_gr_h + +#define cet_cs_name_csa_z243_4_1985_gr "CSA_Z243.4-1985-gr" + +const char *cet_cs_alias_csa_z243_4_1985_gr[] = +{ + "CSA_Z243.4-1985-gr", "iso-ir-123", NULL +}; + +#define cet_ucs4_ofs_csa_z243_4_1985_gr 162 +#define cet_ucs4_cnt_csa_z243_4_1985_gr 94 + +const int cet_ucs4_map_csa_z243_4_1985_gr[cet_ucs4_cnt_csa_z243_4_1985_gr] = +{ + 0x00a8, 0x00a3, 0x00a2, 0x00a5, 0x00b1, 0x00b4, 0x207d, 0x207e, + 0x00bd, 0x207a, 0x00b8, 0x00ad, 0x00b7, 0x207b, 0x2070, 0x00b9, + 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, + 0x00bc, 0x00be, 0x21d0, 0x2260, 0x2265, 0x00bf, 0x00c0, 0x00c1, + 0x00c2, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cd, 0x00ce, + 0x00cf, 0x00d1, 0x00d3, 0x00d4, 0x00d9, 0x00da, 0x00db, 0x00dc, + 0x00ae, 0x00a7, 0x00b6, 0x00b5, 0x00aa, 0x00ba, 0x2018, 0x2019, + 0x201c, 0x201d, 0x00ab, 0x00bb, 0x00b0, 0x00a6, 0x00e0, 0x00e1, + 0x00e2, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ed, 0x00ee, + 0x00ef, 0x00f1, 0x00f3, 0x00f4, 0x00f9, 0x00fa, 0x00fb, 0x00fc, + 0x00a9, 0x2500, 0x2502, 0x2514, 0x2518, 0x2510, 0x250c, 0x251c, + 0x2534, 0x2524, 0x252c, 0x253c, 0x00ac, 0x2588 +}; + +#define cet_ucs4_to_csa_z243_4_1985_gr_ct 82 + +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_gr_links[cet_ucs4_to_csa_z243_4_1985_gr_ct] = +{ + {0x00a2, 0xa4} /* sign */, + {0x00a6, 0xdf} /* bar */, + {0x00a7, 0xd3} /* sign */, + {0x00a8, 0xa2} /* diaeresis */, + {0x00a9, 0xf2} /* sign */, + {0x00aa, 0xd6} /* ordinal indicator */, + {0x00ab, 0xdc} /* double angle quotation mark */, + {0x00ac, 0xfe} /* sign */, + {0x00ae, 0xd2} /* sign */, + {0x00b0, 0xde} /* sign */, + {0x00b1, 0xa6} /* sign */, + {0x00b4, 0xa7} /* accent */, + {0x00b5, 0xd5} /* sign */, + {0x00b6, 0xd4} /* sign */, + {0x00b7, 0xae} /* dot */, + {0x00b8, 0xac} /* cedilla */, + {0x00b9, 0xb1} /* one */, + {0x00ba, 0xd7} /* ordinal indicator */, + {0x00bb, 0xdd} /* double angle quotation mark */, + {0x00bc, 0xba} /* fraction one quarter */, + {0x00bd, 0xaa} /* fraction one half */, + {0x00be, 0xbb} /* fraction three quarters */, + {0x00c7, 0xc3} /* capital letter c with cedilla */, + {0x00c8, 0xc4} /* capital letter e with grave */, + {0x00c9, 0xc5} /* capital letter e with acute */, + {0x00ca, 0xc6} /* capital letter e with circumflex */, + {0x00cb, 0xc7} /* capital letter e with diaeresis */, + {0x00cd, 0xc8} /* capital letter i with acute */, + {0x00ce, 0xc9} /* capital letter i with circumflex */, + {0x00cf, 0xca} /* capital letter i with diaeresis */, + {0x00d1, 0xcb} /* capital letter n with tilde */, + {0x00d3, 0xcc} /* capital letter o with acute */, + {0x00d4, 0xcd} /* capital letter o with circumflex */, + {0x00d9, 0xce} /* capital letter u with grave */, + {0x00da, 0xcf} /* capital letter u with acute */, + {0x00db, 0xd0} /* capital letter u with circumflex */, + {0x00dc, 0xd1} /* capital letter u with diaeresis */, + {0x00e7, 0xe3} /* small letter c with cedilla */, + {0x00e8, 0xe4} /* small letter e with grave */, + {0x00e9, 0xe5} /* small letter e with acute */, + {0x00ea, 0xe6} /* small letter e with circumflex */, + {0x00eb, 0xe7} /* small letter e with diaeresis */, + {0x00ed, 0xe8} /* small letter i with acute */, + {0x00ee, 0xe9} /* small letter i with circumflex */, + {0x00ef, 0xea} /* small letter i with diaeresis */, + {0x00f1, 0xeb} /* small letter n with tilde */, + {0x00f3, 0xec} /* small letter o with acute */, + {0x00f4, 0xed} /* small letter o with circumflex */, + {0x00f9, 0xee} /* small letter u with grave */, + {0x00fa, 0xef} /* small letter u with acute */, + {0x00fb, 0xf0} /* small letter u with circumflex */, + {0x00fc, 0xf1} /* small letter u with diaeresis */, + {0x2018, 0xd8} /* single quotation mark */, + {0x2019, 0xd9} /* single quotation mark */, + {0x201c, 0xda} /* double quotation mark */, + {0x201d, 0xdb} /* double quotation mark */, + {0x2070, 0xb0} /* digit zero */, + {0x2074, 0xb4} /* digit four */, + {0x2075, 0xb5} /* digit five */, + {0x2076, 0xb6} /* digit six */, + {0x2077, 0xb7} /* digit seven */, + {0x2078, 0xb8} /* digit eight */, + {0x2079, 0xb9} /* digit nine */, + {0x207a, 0xab} /* plus sign */, + {0x207b, 0xaf} /* minus */, + {0x207d, 0xa8} /* left parenthesis */, + {0x207e, 0xa9} /* right parenthesis */, + {0x21d0, 0xbc} /* double arrow */, + {0x2260, 0xbd} /* equal to */, + {0x2265, 0xbe} /* or equal to */, + {0x2500, 0xf3} /* drawings light horizontal */, + {0x2502, 0xf4} /* drawings light vertical */, + {0x250c, 0xf8} /* drawings light down and right */, + {0x2510, 0xf7} /* drawings light down and left */, + {0x2514, 0xf5} /* drawings light up and right */, + {0x2518, 0xf6} /* drawings light up and left */, + {0x251c, 0xf9} /* drawings light vertical and right */, + {0x2524, 0xfb} /* drawings light vertical and left */, + {0x252c, 0xfc} /* drawings light down and horizontal */, + {0x2534, 0xfa} /* drawings light up and horizontal */, + {0x253c, 0xfd} /* drawings light vertical and horizontal */, + {0x2588, 0xff} /* block */ +}; + +/* +#define cet_ucs4_to_csa_z243_4_1985_gr_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csa_z243_4_1985_gr_extra[cet_ucs4_to_csa_z243_4_1985_gr_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csa_z243_4_1985_gr = /* defined in cet.h */ +{ + cet_cs_name_csa_z243_4_1985_gr, /* name of character set */ + cet_cs_alias_csa_z243_4_1985_gr, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csa_z243_4_1985_gr, /* char to UCS-4 value table */ + cet_ucs4_ofs_csa_z243_4_1985_gr, /* first non standard character */ + cet_ucs4_cnt_csa_z243_4_1985_gr, /* number of values in table */ + + cet_ucs4_to_csa_z243_4_1985_gr_links, /* UCS-4 to char links */ + cet_ucs4_to_csa_z243_4_1985_gr_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csa_z243_4_1985_gr_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a8, 0x00a3, 0x00a2, 0x00a5, 0x00b1, 0x00b4, + 0x207d, 0x207e, 0x00bd, 0x207a, 0x00b8, 0x00ad, 0x00b7, 0x207b, + 0x2070, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, + 0x2078, 0x2079, 0x00bc, 0x00be, 0x21d0, 0x2260, 0x2265, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, + 0x00cd, 0x00ce, 0x00cf, 0x00d1, 0x00d3, 0x00d4, 0x00d9, 0x00da, + 0x00db, 0x00dc, 0x00ae, 0x00a7, 0x00b6, 0x00b5, 0x00aa, 0x00ba, + 0x2018, 0x2019, 0x201c, 0x201d, 0x00ab, 0x00bb, 0x00b0, 0x00a6, + 0x00e0, 0x00e1, 0x00e2, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ed, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f4, 0x00f9, 0x00fa, + 0x00fb, 0x00fc, 0x00a9, 0x2500, 0x2502, 0x2514, 0x2518, 0x2510, + 0x250c, 0x251c, 0x2534, 0x2524, 0x252c, 0x253c, 0x00ac, 0x2588 +}; +*/ + +#endif diff --git a/cet/csn_369103.h b/cet/csn_369103.h new file mode 100644 index 000000000..4b6cca844 --- /dev/null +++ b/cet/csn_369103.h @@ -0,0 +1,200 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CSN_369103" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef csn_369103_h +#define csn_369103_h + +#define cet_cs_name_csn_369103 "CSN_369103" + +const char *cet_cs_alias_csn_369103[] = +{ + "CSN_369103", "iso-ir-139", "koi8l2", "KOI-8_L2", + NULL +}; + +#define cet_ucs4_ofs_csn_369103 36 +#define cet_ucs4_cnt_csn_369103 220 + +const int cet_ucs4_map_csn_369103[cet_ucs4_cnt_csn_369103] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, 0x0104, 0x02d8, 0x0141, + 0x0024, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, + 0x0179, 0x00ad, 0x017d, 0x017b, 0x00b0, 0x0105, 0x02db, 0x0142, + 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, + 0x017a, 0x02dd, 0x017e, 0x017c, 0x0154, 0x00c1, 0x00c2, 0x0102, + 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, + 0x011a, 0x00cd, 0x00ce, 0x010e, 0x0110, 0x0143, 0x0147, 0x00d3, + 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, + 0x00dc, 0x00dd, 0x0162, 0x00df, 0x0155, 0x00e1, 0x00e2, 0x0103, + 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, + 0x011b, 0x00ed, 0x00ee, 0x010f, 0x0111, 0x0144, 0x0148, 0x00f3, + 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, + 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +#define cet_ucs4_to_csn_369103_ct 59 + +const cet_ucs4_link_t cet_ucs4_to_csn_369103_links[cet_ucs4_to_csn_369103_ct] = +{ + {0x0024, 0xa4} /* sign */, + {0x00a4, 0x24} /* sign */, + {0x0102, 0xc3} /* capital letter a with breve */, + {0x0103, 0xe3} /* small letter a with breve */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x0106, 0xc6} /* capital letter c with acute */, + {0x0107, 0xe6} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x010e, 0xcf} /* capital letter d with caron */, + {0x010f, 0xef} /* small letter d with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011a, 0xcc} /* capital letter e with caron */, + {0x011b, 0xec} /* small letter e with caron */, + {0x0139, 0xc5} /* capital letter l with acute */, + {0x013a, 0xe5} /* small letter l with acute */, + {0x013d, 0xa5} /* capital letter l with caron */, + {0x013e, 0xb5} /* small letter l with caron */, + {0x0141, 0xa3} /* capital letter l with stroke */, + {0x0142, 0xb3} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0147, 0xd2} /* capital letter n with caron */, + {0x0148, 0xf2} /* small letter n with caron */, + {0x0150, 0xd5} /* capital letter o with double acute */, + {0x0151, 0xf5} /* small letter o with double acute */, + {0x0154, 0xc0} /* capital letter r with acute */, + {0x0155, 0xe0} /* small letter r with acute */, + {0x0158, 0xd8} /* capital letter r with caron */, + {0x0159, 0xf8} /* small letter r with caron */, + {0x015a, 0xa6} /* capital letter s with acute */, + {0x015b, 0xb6} /* small letter s with acute */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x0160, 0xa9} /* capital letter s with caron */, + {0x0161, 0xb9} /* small letter s with caron */, + {0x0162, 0xde} /* capital letter t with cedilla */, + {0x0163, 0xfe} /* small letter t with cedilla */, + {0x0164, 0xab} /* capital letter t with caron */, + {0x0165, 0xbb} /* small letter t with caron */, + {0x016e, 0xd9} /* capital letter u with ring above */, + {0x016f, 0xf9} /* small letter u with ring above */, + {0x0170, 0xdb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0xac} /* capital letter z with acute */, + {0x017a, 0xbc} /* small letter z with acute */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x017d, 0xae} /* capital letter z with caron */, + {0x017e, 0xbe} /* small letter z with caron */, + {0x02c7, 0xb7} /* caron */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */, + {0x02dd, 0xbd} /* acute accent */ +}; + +/* +#define cet_ucs4_to_csn_369103_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_csn_369103_extra[cet_ucs4_to_csn_369103_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_csn_369103 = /* defined in cet.h */ +{ + cet_cs_name_csn_369103, /* name of character set */ + cet_cs_alias_csn_369103, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_csn_369103, /* char to UCS-4 value table */ + cet_ucs4_ofs_csn_369103, /* first non standard character */ + cet_ucs4_cnt_csn_369103, /* number of values in table */ + + cet_ucs4_to_csn_369103_links, /* UCS-4 to char links */ + cet_ucs4_to_csn_369103_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int csn_369103_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x0024, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; +*/ + +#endif diff --git a/cet/cwi.h b/cet/cwi.h new file mode 100644 index 000000000..3b5be2206 --- /dev/null +++ b/cet/cwi.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "CWI" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef cwi_h +#define cwi_h + +#define cet_cs_name_cwi "CWI" + +const char *cet_cs_alias_cwi[] = +{ + "CWI", "cp-hu", "CWI-2", NULL +}; + +#define cet_ucs4_ofs_cwi 128 +#define cet_ucs4_cnt_cwi 128 + +const int cet_ucs4_map_cwi[cet_ucs4_cnt_cwi] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00cd, 0x00c4, 0x00c1, + 0x00c9, 0x00e6, 0x00c6, 0x0151, 0x00f6, 0x00d3, 0x0171, 0x00da, + 0x0170, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0xe01f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x0150, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_cwi_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_cwi_links[cet_ucs4_to_cwi_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a5, 0x9d} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b7, 0xf9} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c1, 0x8f} /* capital letter a with acute */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cd, 0x8d} /* capital letter i with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d3, 0x95} /* capital letter o with acute */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00da, 0x97} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x0150, 0xa7} /* capital letter o with double acute */, + {0x0151, 0x93} /* small letter o with double acute */, + {0x0170, 0x98} /* capital letter u with double acute */, + {0x0171, 0x96} /* small letter u with double acute */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b2, 0xe1} /* small letter beta */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */, + {0xe01f, 0x9f} /* guilder sign (ibm437 159) */ +}; + +/* +#define cet_ucs4_to_cwi_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_cwi_extra[cet_ucs4_to_cwi_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_cwi = /* defined in cet.h */ +{ + cet_cs_name_cwi, /* name of character set */ + cet_cs_alias_cwi, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_cwi, /* char to UCS-4 value table */ + cet_ucs4_ofs_cwi, /* first non standard character */ + cet_ucs4_cnt_cwi, /* number of values in table */ + + cet_ucs4_to_cwi_links, /* UCS-4 to char links */ + cet_ucs4_to_cwi_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int cwi_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00cd, 0x00c4, 0x00c1, + 0x00c9, 0x00e6, 0x00c6, 0x0151, 0x00f6, 0x00d3, 0x0171, 0x00da, + 0x0170, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0xe01f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x0150, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/dec_mcs.h b/cet/dec_mcs.h new file mode 100644 index 000000000..b7a319df8 --- /dev/null +++ b/cet/dec_mcs.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "DEC-MCS" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef dec_mcs_h +#define dec_mcs_h + +#define cet_cs_name_dec_mcs "DEC-MCS" + +const char *cet_cs_alias_dec_mcs[] = +{ + "DEC-MCS", "dec", NULL +}; + +#define cet_ucs4_ofs_dec_mcs 160 +#define cet_ucs4_cnt_dec_mcs 94 + +const int cet_ucs4_map_dec_mcs[cet_ucs4_cnt_dec_mcs] = +{ + -1, 0x00a1, 0x00a2, 0x00a3, -1, 0x00a5, -1, 0x00a7, + 0x00a4, 0x00a9, 0x00aa, 0x00ab, -1, -1, -1, -1, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + -1, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, -1, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + -1, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0152, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0178, -1, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + -1, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0153, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00ff +}; + +#define cet_ucs4_to_dec_mcs_ct 5 + +const cet_ucs4_link_t cet_ucs4_to_dec_mcs_links[cet_ucs4_to_dec_mcs_ct] = +{ + {0x00a4, 0xa8} /* sign */, + {0x00ff, 0xfd} /* small letter y with diaeresis */, + {0x0152, 0xd7} /* capital ligature oe */, + {0x0153, 0xf7} /* small ligature oe */, + {0x0178, 0xdd} /* capital letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_dec_mcs_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_dec_mcs_extra[cet_ucs4_to_dec_mcs_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_dec_mcs = /* defined in cet.h */ +{ + cet_cs_name_dec_mcs, /* name of character set */ + cet_cs_alias_dec_mcs, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_dec_mcs, /* char to UCS-4 value table */ + cet_ucs4_ofs_dec_mcs, /* first non standard character */ + cet_ucs4_cnt_dec_mcs, /* number of values in table */ + + cet_ucs4_to_dec_mcs_links, /* UCS-4 to char links */ + cet_ucs4_to_dec_mcs_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int dec_mcs_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, 0x00a1, 0x00a2, 0x00a3, -1, 0x00a5, -1, 0x00a7, + 0x00a4, 0x00a9, 0x00aa, 0x00ab, -1, -1, -1, -1, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, -1, 0x00b5, 0x00b6, 0x00b7, + -1, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, -1, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + -1, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0152, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0178, -1, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + -1, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0153, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00ff, -1, -1 +}; +*/ + +#endif diff --git a/cet/din_66003.h b/cet/din_66003.h new file mode 100644 index 000000000..cd0b69d18 --- /dev/null +++ b/cet/din_66003.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "DIN_66003" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef din_66003_h +#define din_66003_h + +#define cet_cs_name_din_66003 "DIN_66003" + +const char *cet_cs_alias_din_66003[] = +{ + "DIN_66003", "de", "ISO646-DE", "iso-ir-21", + NULL +}; + +#define cet_ucs4_ofs_din_66003 64 +#define cet_ucs4_cnt_din_66003 64 + +const int cet_ucs4_map_din_66003[cet_ucs4_cnt_din_66003] = +{ + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00fc, 0x00df, 0x007f +}; + +#define cet_ucs4_to_din_66003_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_din_66003_links[cet_ucs4_to_din_66003_ct] = +{ + {0x00a7, 0x40} /* sign */, + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00dc, 0x5d} /* capital letter u with diaeresis */, + {0x00df, 0x7e} /* small letter sharp s (german) */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x00fc, 0x7d} /* small letter u with diaeresis */ +}; + +/* +#define cet_ucs4_to_din_66003_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_din_66003_extra[cet_ucs4_to_din_66003_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_din_66003 = /* defined in cet.h */ +{ + cet_cs_name_din_66003, /* name of character set */ + cet_cs_alias_din_66003, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_din_66003, /* char to UCS-4 value table */ + cet_ucs4_ofs_din_66003, /* first non standard character */ + cet_ucs4_cnt_din_66003, /* number of values in table */ + + cet_ucs4_to_din_66003_links, /* UCS-4 to char links */ + cet_ucs4_to_din_66003_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int din_66003_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00fc, 0x00df, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ds_2089.h b/cet/ds_2089.h new file mode 100644 index 000000000..1035225e7 --- /dev/null +++ b/cet/ds_2089.h @@ -0,0 +1,124 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "DS_2089" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ds_2089_h +#define ds_2089_h + +#define cet_cs_name_ds_2089 "DS_2089" + +const char *cet_cs_alias_ds_2089[] = +{ + "DS_2089", "dk", "DS2089", "ISO646-DK", + NULL +}; + +#define cet_ucs4_ofs_ds_2089 91 +#define cet_ucs4_cnt_ds_2089 37 + +const int cet_ucs4_map_ds_2089[cet_ucs4_cnt_ds_2089] = +{ + 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e6, 0x00f8, 0x00e5, 0x007e, 0x007f +}; + +#define cet_ucs4_to_ds_2089_ct 6 + +const cet_ucs4_link_t cet_ucs4_to_ds_2089_links[cet_ucs4_to_ds_2089_ct] = +{ + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */ +}; + +/* +#define cet_ucs4_to_ds_2089_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ds_2089_extra[cet_ucs4_to_ds_2089_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ds_2089 = /* defined in cet.h */ +{ + cet_cs_name_ds_2089, /* name of character set */ + cet_cs_alias_ds_2089, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ds_2089, /* char to UCS-4 value table */ + cet_ucs4_ofs_ds_2089, /* first non standard character */ + cet_ucs4_cnt_ds_2089, /* number of values in table */ + + cet_ucs4_to_ds_2089_links, /* UCS-4 to char links */ + cet_ucs4_to_ds_2089_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ds_2089_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ecma_cyrillic.h b/cet/ecma_cyrillic.h new file mode 100644 index 000000000..dda8a7058 --- /dev/null +++ b/cet/ecma_cyrillic.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ECMA-cyrillic" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ecma_cyrillic_h +#define ecma_cyrillic_h + +#define cet_cs_name_ecma_cyrillic "ECMA-cyrillic" + +const char *cet_cs_alias_ecma_cyrillic[] = +{ + "ECMA-cyrillic", "ECMA-113", "ECMA-113:1986", "iso-ir-111", + NULL +}; + +#define cet_ucs4_ofs_ecma_cyrillic 161 +#define cet_ucs4_cnt_ecma_cyrillic 95 + +const int cet_ucs4_map_ecma_cyrillic[cet_ucs4_cnt_ecma_cyrillic] = +{ + 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x00ad, 0x045e, 0x045f, 0x2116, + 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040a, 0x040b, 0x040c, 0x00a4, 0x040e, 0x040f, 0x044e, + 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044c, + 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, 0x042e, + 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, + 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; + +#define cet_ucs4_to_ecma_cyrillic_ct 94 + +const cet_ucs4_link_t cet_ucs4_to_ecma_cyrillic_links[cet_ucs4_to_ecma_cyrillic_ct] = +{ + {0x00a4, 0xbd} /* sign */, + {0x0401, 0xb3} /* capital letter io */, + {0x0402, 0xb1} /* capital letter dje (serbocroatian) */, + {0x0403, 0xb2} /* capital letter gje (macedonian) */, + {0x0404, 0xb4} /* capital letter ukrainian ie */, + {0x0405, 0xb5} /* capital letter dze (macedonian) */, + {0x0406, 0xb6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xb7} /* capital letter yi (ukrainian) */, + {0x0408, 0xb8} /* capital letter je */, + {0x0409, 0xb9} /* capital letter lje */, + {0x040a, 0xba} /* capital letter nje */, + {0x040b, 0xbb} /* capital letter tshe (serbocroatian) */, + {0x040c, 0xbc} /* capital letter kje (macedonian) */, + {0x040e, 0xbe} /* capital letter short u (byelorussian) */, + {0x040f, 0xbf} /* capital letter dzhe */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042a, 0xff} /* capital letter hard sign */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x0452, 0xa1} /* small letter dje (serbocroatian) */, + {0x0453, 0xa2} /* small letter gje (macedonian) */, + {0x0454, 0xa4} /* small letter ukrainian ie */, + {0x0455, 0xa5} /* small letter dze (macedonian) */, + {0x0456, 0xa6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xa7} /* small letter yi (ukrainian) */, + {0x0458, 0xa8} /* small letter je */, + {0x0459, 0xa9} /* small letter lje */, + {0x045a, 0xaa} /* small letter nje */, + {0x045b, 0xab} /* small letter tshe (serbocroatian) */, + {0x045c, 0xac} /* small letter kje (macedonian) */, + {0x045e, 0xae} /* small letter short u (byelorussian) */, + {0x045f, 0xaf} /* small letter dzhe */, + {0x2116, 0xb0} /* sign */ +}; + +/* +#define cet_ucs4_to_ecma_cyrillic_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ecma_cyrillic_extra[cet_ucs4_to_ecma_cyrillic_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ecma_cyrillic = /* defined in cet.h */ +{ + cet_cs_name_ecma_cyrillic, /* name of character set */ + cet_cs_alias_ecma_cyrillic, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ecma_cyrillic, /* char to UCS-4 value table */ + cet_ucs4_ofs_ecma_cyrillic, /* first non standard character */ + cet_ucs4_cnt_ecma_cyrillic, /* number of values in table */ + + cet_ucs4_to_ecma_cyrillic_links, /* UCS-4 to char links */ + cet_ucs4_to_ecma_cyrillic_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ecma_cyrillic_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00ad, 0x045e, 0x045f, + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00a4, 0x040e, 0x040f, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; +*/ + +#endif diff --git a/cet/es.h b/cet/es.h new file mode 100644 index 000000000..4fd66e8a0 --- /dev/null +++ b/cet/es.h @@ -0,0 +1,132 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ES" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef es_h +#define es_h + +#define cet_cs_name_es "ES" + +const char *cet_cs_alias_es[] = +{ + "ES", "ISO646-ES", "iso-ir-17", NULL +}; + +#define cet_ucs4_ofs_es 35 +#define cet_ucs4_cnt_es 93 + +const int cet_ucs4_map_es[cet_ucs4_cnt_es] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00a7, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00b0, 0x00f1, 0x00e7, 0x007e, 0x007f +}; + +#define cet_ucs4_to_es_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_es_links[cet_ucs4_to_es_ct] = +{ + {0x00a1, 0x5b} /* exclamation mark */, + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x40} /* sign */, + {0x00b0, 0x7b} /* sign */, + {0x00bf, 0x5d} /* question mark */, + {0x00d1, 0x5c} /* capital letter n with tilde */, + {0x00e7, 0x7d} /* small letter c with cedilla */, + {0x00f1, 0x7c} /* small letter n with tilde */ +}; + +/* +#define cet_ucs4_to_es_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_es_extra[cet_ucs4_to_es_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_es = /* defined in cet.h */ +{ + cet_cs_name_es, /* name of character set */ + cet_cs_alias_es, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_es, /* char to UCS-4 value table */ + cet_ucs4_ofs_es, /* first non standard character */ + cet_ucs4_cnt_es, /* number of values in table */ + + cet_ucs4_to_es_links, /* UCS-4 to char links */ + cet_ucs4_to_es_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int es_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b0, 0x00f1, 0x00e7, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/es2.h b/cet/es2.h new file mode 100644 index 000000000..ec3e2a91b --- /dev/null +++ b/cet/es2.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ES2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef es2_h +#define es2_h + +#define cet_cs_name_es2 "ES2" + +const char *cet_cs_alias_es2[] = +{ + "ES2", "ISO646-ES2", "iso-ir-85", NULL +}; + +#define cet_ucs4_ofs_es2 64 +#define cet_ucs4_cnt_es2 64 + +const int cet_ucs4_map_es2[cet_ucs4_cnt_es2] = +{ + 0x2022, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00c7, 0x00bf, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b4, 0x00f1, 0x00e7, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_es2_ct 9 + +const cet_ucs4_link_t cet_ucs4_to_es2_links[cet_ucs4_to_es2_ct] = +{ + {0x00a1, 0x5b} /* exclamation mark */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b4, 0x7b} /* accent */, + {0x00bf, 0x5e} /* question mark */, + {0x00c7, 0x5d} /* capital letter c with cedilla */, + {0x00d1, 0x5c} /* capital letter n with tilde */, + {0x00e7, 0x7d} /* small letter c with cedilla */, + {0x00f1, 0x7c} /* small letter n with tilde */, + {0x2022, 0x40} /* puce */ +}; + +/* +#define cet_ucs4_to_es2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_es2_extra[cet_ucs4_to_es2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_es2 = /* defined in cet.h */ +{ + cet_cs_name_es2, /* name of character set */ + cet_cs_alias_es2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_es2, /* char to UCS-4 value table */ + cet_ucs4_ofs_es2, /* first non standard character */ + cet_ucs4_cnt_es2, /* number of values in table */ + + cet_ucs4_to_es2_links, /* UCS-4 to char links */ + cet_ucs4_to_es2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int es2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x2022, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x00c7, 0x00bf, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b4, 0x00f1, 0x00e7, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/gb_1988_80.h b/cet/gb_1988_80.h new file mode 100644 index 000000000..90cb5fbb0 --- /dev/null +++ b/cet/gb_1988_80.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "GB_1988-80" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef gb_1988_80_h +#define gb_1988_80_h + +#define cet_cs_name_gb_1988_80 "GB_1988-80" + +const char *cet_cs_alias_gb_1988_80[] = +{ + "GB_1988-80", "cn", "csISO57GB1988", "ISO646-CN", + "iso-ir-57", NULL +}; + +#define cet_ucs4_ofs_gb_1988_80 36 +#define cet_ucs4_cnt_gb_1988_80 92 + +const int cet_ucs4_map_gb_1988_80[cet_ucs4_cnt_gb_1988_80] = +{ + 0x00a5, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_gb_1988_80_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_gb_1988_80_links[cet_ucs4_to_gb_1988_80_ct] = +{ + {0x00a5, 0x24} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_gb_1988_80_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_gb_1988_80_extra[cet_ucs4_to_gb_1988_80_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_gb_1988_80 = /* defined in cet.h */ +{ + cet_cs_name_gb_1988_80, /* name of character set */ + cet_cs_alias_gb_1988_80, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_gb_1988_80, /* char to UCS-4 value table */ + cet_ucs4_ofs_gb_1988_80, /* first non standard character */ + cet_ucs4_cnt_gb_1988_80, /* number of values in table */ + + cet_ucs4_to_gb_1988_80_links, /* UCS-4 to char links */ + cet_ucs4_to_gb_1988_80_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int gb_1988_80_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a5, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/gost_19768_87.h b/cet/gost_19768_87.h new file mode 100644 index 000000000..6a18ac504 --- /dev/null +++ b/cet/gost_19768_87.h @@ -0,0 +1,189 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "GOST_19768-87" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef gost_19768_87_h +#define gost_19768_87_h + +#define cet_cs_name_gost_19768_87 "GOST_19768-87" + +const char *cet_cs_alias_gost_19768_87[] = +{ + "GOST_19768-87", "iso-ir-153", "ST_SEV_358-88", NULL +}; + +#define cet_ucs4_ofs_gost_19768_87 161 +#define cet_ucs4_cnt_gost_19768_87 81 + +const int cet_ucs4_map_gost_19768_87[cet_ucs4_cnt_gost_19768_87] = +{ + 0x0401, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 0x00ad, -1, -1, 0x0410, + 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, + 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, + 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, + 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, + 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, + 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, -1, + 0x0451 +}; + +#define cet_ucs4_to_gost_19768_87_ct 66 + +const cet_ucs4_link_t cet_ucs4_to_gost_19768_87_links[cet_ucs4_to_gost_19768_87_ct] = +{ + {0x0401, 0xa1} /* capital letter io */, + {0x0410, 0xb0} /* capital letter a */, + {0x0411, 0xb1} /* capital letter be */, + {0x0412, 0xb2} /* capital letter ve */, + {0x0413, 0xb3} /* capital letter ghe */, + {0x0414, 0xb4} /* capital letter de */, + {0x0415, 0xb5} /* capital letter ie */, + {0x0416, 0xb6} /* capital letter zhe */, + {0x0417, 0xb7} /* capital letter ze */, + {0x0418, 0xb8} /* capital letter i */, + {0x0419, 0xb9} /* capital letter short i */, + {0x041a, 0xba} /* capital letter ka */, + {0x041b, 0xbb} /* capital letter el */, + {0x041c, 0xbc} /* capital letter em */, + {0x041d, 0xbd} /* capital letter en */, + {0x041e, 0xbe} /* capital letter o */, + {0x041f, 0xbf} /* capital letter pe */, + {0x0420, 0xc0} /* capital letter er */, + {0x0421, 0xc1} /* capital letter es */, + {0x0422, 0xc2} /* capital letter te */, + {0x0423, 0xc3} /* capital letter u */, + {0x0424, 0xc4} /* capital letter ef */, + {0x0425, 0xc5} /* capital letter ha */, + {0x0426, 0xc6} /* capital letter tse */, + {0x0427, 0xc7} /* capital letter che */, + {0x0428, 0xc8} /* capital letter sha */, + {0x0429, 0xc9} /* capital letter shcha */, + {0x042a, 0xca} /* capital letter hard sign */, + {0x042b, 0xcb} /* capital letter yeru */, + {0x042c, 0xcc} /* capital letter soft sign */, + {0x042d, 0xcd} /* capital letter e */, + {0x042e, 0xce} /* capital letter yu */, + {0x042f, 0xcf} /* capital letter ya */, + {0x0430, 0xd0} /* small letter a */, + {0x0431, 0xd1} /* small letter be */, + {0x0432, 0xd2} /* small letter ve */, + {0x0433, 0xd3} /* small letter ghe */, + {0x0434, 0xd4} /* small letter de */, + {0x0435, 0xd5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xd7} /* small letter ze */, + {0x0438, 0xd8} /* small letter i */, + {0x0439, 0xd9} /* small letter short i */, + {0x043a, 0xda} /* small letter ka */, + {0x043b, 0xdb} /* small letter el */, + {0x043c, 0xdc} /* small letter em */, + {0x043d, 0xdd} /* small letter en */, + {0x043e, 0xde} /* small letter o */, + {0x043f, 0xdf} /* small letter pe */, + {0x0440, 0xe0} /* small letter er */, + {0x0441, 0xe1} /* small letter es */, + {0x0442, 0xe2} /* small letter te */, + {0x0443, 0xe3} /* small letter u */, + {0x0444, 0xe4} /* small letter ef */, + {0x0445, 0xe5} /* small letter ha */, + {0x0446, 0xe6} /* small letter tse */, + {0x0447, 0xe7} /* small letter che */, + {0x0448, 0xe8} /* small letter sha */, + {0x0449, 0xe9} /* small letter shcha */, + {0x044a, 0xea} /* small letter hard sign */, + {0x044b, 0xeb} /* small letter yeru */, + {0x044c, 0xec} /* small letter soft sign */, + {0x044d, 0xed} /* small letter e */, + {0x044e, 0xee} /* small letter yu */, + {0x044f, 0xef} /* small letter ya */, + {0x0451, 0xf1} /* small letter io */ +}; + +/* +#define cet_ucs4_to_gost_19768_87_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_gost_19768_87_extra[cet_ucs4_to_gost_19768_87_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_gost_19768_87 = /* defined in cet.h */ +{ + cet_cs_name_gost_19768_87, /* name of character set */ + cet_cs_alias_gost_19768_87, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_gost_19768_87, /* char to UCS-4 value table */ + cet_ucs4_ofs_gost_19768_87, /* first non standard character */ + cet_ucs4_cnt_gost_19768_87, /* number of values in table */ + + cet_ucs4_to_gost_19768_87_links, /* UCS-4 to char links */ + cet_ucs4_to_gost_19768_87_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int gost_19768_87_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0401, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0x00ad, -1, -1, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + -1, 0x0451, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/hp_roman8.h b/cet/hp_roman8.h new file mode 100644 index 000000000..8663e43b8 --- /dev/null +++ b/cet/hp_roman8.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "hp-roman8" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef hp_roman8_h +#define hp_roman8_h + +#define cet_cs_name_hp_roman8 "hp-roman8" + +const char *cet_cs_alias_hp_roman8[] = +{ + "hp-roman8", "csHPRoman8", "r8", "roman8", + NULL +}; + +#define cet_ucs4_ofs_hp_roman8 161 +#define cet_ucs4_cnt_hp_roman8 94 + +const int cet_ucs4_map_hp_roman8[cet_ucs4_cnt_hp_roman8] = +{ + 0x00c0, 0x00c2, 0x00c8, 0x00ca, 0x00cb, 0x00ce, 0x00cf, 0x00b4, + 0x02cb, 0x02c6, 0x00a8, 0x02dc, 0x00d9, 0x00db, 0x20a4, 0x00af, + 0x00dd, 0x00fd, 0x00b0, 0x00c7, 0x00e7, 0x00d1, 0x00f1, 0x00a1, + 0x00bf, 0x00a4, 0x00a3, 0x00a5, 0x00a7, 0x0192, 0x00a2, 0x00e2, + 0x00ea, 0x00f4, 0x00fb, 0x00e1, 0x00e9, 0x00f3, 0x00fa, 0x00e0, + 0x00e8, 0x00f2, 0x00f9, 0x00e4, 0x00eb, 0x00f6, 0x00fc, 0x00c5, + 0x00ee, 0x00d8, 0x00c6, 0x00e5, 0x00ed, 0x00f8, 0x00e6, 0x00c4, + 0x00ec, 0x00d6, 0x00dc, 0x00c9, 0x00ef, 0x00df, 0x00d4, 0x00c1, + 0x00c3, 0x00e3, 0x00d0, 0x00f0, 0x00cd, 0x00cc, 0x00d3, 0x00d2, + 0x00d5, 0x00f5, 0x0160, 0x0161, 0x00da, 0x0178, 0x00ff, 0x00de, + 0x00fe, 0x00b7, 0x00b5, 0x00b6, 0x00be, 0x2014, 0x00bc, 0x00bd, + 0x00aa, 0x00ba, 0x00ab, 0x25a0, 0x00bb, 0x00b1 +}; + +#define cet_ucs4_to_hp_roman8_ct 94 + +const cet_ucs4_link_t cet_ucs4_to_hp_roman8_links[cet_ucs4_to_hp_roman8_ct] = +{ + {0x00a1, 0xb8} /* exclamation mark */, + {0x00a2, 0xbf} /* sign */, + {0x00a3, 0xbb} /* sign */, + {0x00a4, 0xba} /* sign */, + {0x00a5, 0xbc} /* sign */, + {0x00a7, 0xbd} /* sign */, + {0x00a8, 0xab} /* diaeresis */, + {0x00aa, 0xf9} /* ordinal indicator */, + {0x00ab, 0xfb} /* double angle quotation mark */, + {0x00af, 0xb0} /* macron */, + {0x00b0, 0xb3} /* sign */, + {0x00b1, 0xfe} /* sign */, + {0x00b4, 0xa8} /* accent */, + {0x00b5, 0xf3} /* sign */, + {0x00b6, 0xf4} /* sign */, + {0x00b7, 0xf2} /* dot */, + {0x00ba, 0xfa} /* ordinal indicator */, + {0x00bb, 0xfd} /* double angle quotation mark */, + {0x00bc, 0xf7} /* fraction one quarter */, + {0x00bd, 0xf8} /* fraction one half */, + {0x00be, 0xf5} /* fraction three quarters */, + {0x00bf, 0xb9} /* question mark */, + {0x00c0, 0xa1} /* capital letter a with grave */, + {0x00c1, 0xe0} /* capital letter a with acute */, + {0x00c2, 0xa2} /* capital letter a with circumflex */, + {0x00c3, 0xe1} /* capital letter a with tilde */, + {0x00c4, 0xd8} /* capital letter a with diaeresis */, + {0x00c5, 0xd0} /* capital letter a with ring above */, + {0x00c6, 0xd3} /* capital letter ae */, + {0x00c7, 0xb4} /* capital letter c with cedilla */, + {0x00c8, 0xa3} /* capital letter e with grave */, + {0x00c9, 0xdc} /* capital letter e with acute */, + {0x00ca, 0xa4} /* capital letter e with circumflex */, + {0x00cb, 0xa5} /* capital letter e with diaeresis */, + {0x00cc, 0xe6} /* capital letter i with grave */, + {0x00cd, 0xe5} /* capital letter i with acute */, + {0x00ce, 0xa6} /* capital letter i with circumflex */, + {0x00cf, 0xa7} /* capital letter i with diaeresis */, + {0x00d0, 0xe3} /* capital letter eth (icelandic) */, + {0x00d1, 0xb6} /* capital letter n with tilde */, + {0x00d2, 0xe8} /* capital letter o with grave */, + {0x00d3, 0xe7} /* capital letter o with acute */, + {0x00d4, 0xdf} /* capital letter o with circumflex */, + {0x00d5, 0xe9} /* capital letter o with tilde */, + {0x00d6, 0xda} /* capital letter o with diaeresis */, + {0x00d8, 0xd2} /* capital letter o with stroke */, + {0x00d9, 0xad} /* capital letter u with grave */, + {0x00da, 0xed} /* capital letter u with acute */, + {0x00db, 0xae} /* capital letter u with circumflex */, + {0x00dc, 0xdb} /* capital letter u with diaeresis */, + {0x00dd, 0xb1} /* capital letter y with acute */, + {0x00de, 0xf0} /* capital letter thorn (icelandic) */, + {0x00df, 0xde} /* small letter sharp s (german) */, + {0x00e0, 0xc8} /* small letter a with grave */, + {0x00e1, 0xc4} /* small letter a with acute */, + {0x00e2, 0xc0} /* small letter a with circumflex */, + {0x00e3, 0xe2} /* small letter a with tilde */, + {0x00e4, 0xcc} /* small letter a with diaeresis */, + {0x00e5, 0xd4} /* small letter a with ring above */, + {0x00e6, 0xd7} /* small letter ae */, + {0x00e7, 0xb5} /* small letter c with cedilla */, + {0x00e8, 0xc9} /* small letter e with grave */, + {0x00e9, 0xc5} /* small letter e with acute */, + {0x00ea, 0xc1} /* small letter e with circumflex */, + {0x00eb, 0xcd} /* small letter e with diaeresis */, + {0x00ec, 0xd9} /* small letter i with grave */, + {0x00ed, 0xd5} /* small letter i with acute */, + {0x00ee, 0xd1} /* small letter i with circumflex */, + {0x00ef, 0xdd} /* small letter i with diaeresis */, + {0x00f0, 0xe4} /* small letter eth (icelandic) */, + {0x00f1, 0xb7} /* small letter n with tilde */, + {0x00f2, 0xca} /* small letter o with grave */, + {0x00f3, 0xc6} /* small letter o with acute */, + {0x00f4, 0xc2} /* small letter o with circumflex */, + {0x00f5, 0xea} /* small letter o with tilde */, + {0x00f6, 0xce} /* small letter o with diaeresis */, + {0x00f8, 0xd6} /* small letter o with stroke */, + {0x00f9, 0xcb} /* small letter u with grave */, + {0x00fa, 0xc7} /* small letter u with acute */, + {0x00fb, 0xc3} /* small letter u with circumflex */, + {0x00fc, 0xcf} /* small letter u with diaeresis */, + {0x00fd, 0xb2} /* small letter y with acute */, + {0x00fe, 0xf1} /* small letter thorn (icelandic) */, + {0x00ff, 0xef} /* small letter y with diaeresis */, + {0x0160, 0xeb} /* capital letter s with caron */, + {0x0161, 0xec} /* small letter s with caron */, + {0x0178, 0xee} /* capital letter y with diaeresis */, + {0x0192, 0xbe} /* minuscule latine f hameçon */, + {0x02c6, 0xaa} /* modificative accent circonflexe */, + {0x02cb, 0xa9} /* modificative accent grave */, + {0x02dc, 0xac} /* tilde */, + {0x2014, 0xf6} /* dash */, + {0x20a4, 0xaf} /* sign */, + {0x25a0, 0xfc} /* square */ +}; + +/* +#define cet_ucs4_to_hp_roman8_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_hp_roman8_extra[cet_ucs4_to_hp_roman8_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_hp_roman8 = /* defined in cet.h */ +{ + cet_cs_name_hp_roman8, /* name of character set */ + cet_cs_alias_hp_roman8, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_hp_roman8, /* char to UCS-4 value table */ + cet_ucs4_ofs_hp_roman8, /* first non standard character */ + cet_ucs4_cnt_hp_roman8, /* number of values in table */ + + cet_ucs4_to_hp_roman8_links, /* UCS-4 to char links */ + cet_ucs4_to_hp_roman8_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int hp_roman8_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00c0, 0x00c2, 0x00c8, 0x00ca, 0x00cb, 0x00ce, 0x00cf, + 0x00b4, 0x02cb, 0x02c6, 0x00a8, 0x02dc, 0x00d9, 0x00db, 0x20a4, + 0x00af, 0x00dd, 0x00fd, 0x00b0, 0x00c7, 0x00e7, 0x00d1, 0x00f1, + 0x00a1, 0x00bf, 0x00a4, 0x00a3, 0x00a5, 0x00a7, 0x0192, 0x00a2, + 0x00e2, 0x00ea, 0x00f4, 0x00fb, 0x00e1, 0x00e9, 0x00f3, 0x00fa, + 0x00e0, 0x00e8, 0x00f2, 0x00f9, 0x00e4, 0x00eb, 0x00f6, 0x00fc, + 0x00c5, 0x00ee, 0x00d8, 0x00c6, 0x00e5, 0x00ed, 0x00f8, 0x00e6, + 0x00c4, 0x00ec, 0x00d6, 0x00dc, 0x00c9, 0x00ef, 0x00df, 0x00d4, + 0x00c1, 0x00c3, 0x00e3, 0x00d0, 0x00f0, 0x00cd, 0x00cc, 0x00d3, + 0x00d2, 0x00d5, 0x00f5, 0x0160, 0x0161, 0x00da, 0x0178, 0x00ff, + 0x00de, 0x00fe, 0x00b7, 0x00b5, 0x00b6, 0x00be, 0x2014, 0x00bc, + 0x00bd, 0x00aa, 0x00ba, 0x00ab, 0x25a0, 0x00bb, 0x00b1, -1 +}; +*/ + +#endif diff --git a/cet/ibm037.h b/cet/ibm037.h new file mode 100644 index 000000000..3e4913720 --- /dev/null +++ b/cet/ibm037.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM037" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm037_h +#define ibm037_h + +#define cet_cs_name_ibm037 "IBM037" + +const char *cet_cs_alias_ibm037[] = +{ + "IBM037", "037", "CP037", "ebcdic-cp-ca", + "ebcdic-cp-nl", "ebcdic-cp-us", "ebcdic-cp-wt", NULL +}; + +#define cet_ucs4_ofs_ibm037 4 +#define cet_ucs4_cnt_ibm037 252 + +const int cet_ucs4_map_ibm037[cet_ucs4_cnt_ibm037] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00a2, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x0021, 0x0024, + 0x002a, 0x0029, 0x003b, 0x00ac, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x005e, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x005b, 0x005d, + 0x00af, 0x00a8, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm037_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm037_links[cet_ucs4_to_ibm037_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x5a} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xba} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0xbb} /* square bracket */, + {0x005e, 0xb0} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0x4a} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0x5f} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm037_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm037_extra[cet_ucs4_to_ibm037_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm037 = /* defined in cet.h */ +{ + cet_cs_name_ibm037, /* name of character set */ + cet_cs_alias_ibm037, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm037, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm037, /* first non standard character */ + cet_ucs4_cnt_ibm037, /* number of values in table */ + + cet_ucs4_to_ibm037_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm037_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm037_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00a2, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x0021, 0x0024, 0x002a, 0x0029, 0x003b, 0x00ac, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x005e, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x005b, 0x005d, 0x00af, 0x00a8, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm1004.h b/cet/ibm1004.h new file mode 100644 index 000000000..152dcd9d0 --- /dev/null +++ b/cet/ibm1004.h @@ -0,0 +1,152 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM1004" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm1004_h +#define ibm1004_h + +#define cet_cs_name_ibm1004 "IBM1004" + +const char *cet_cs_alias_ibm1004[] = +{ + "IBM1004", "1004", "CP1004", "os2latin1", + NULL +}; + +#define cet_ucs4_ofs_ibm1004 128 +#define cet_ucs4_cnt_ibm1004 128 + +const int cet_ucs4_map_ibm1004[cet_ucs4_cnt_ibm1004] = +{ + -1, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_ibm1004_ct 23 + +const cet_ucs4_link_t cet_ucs4_to_ibm1004_links[cet_ucs4_to_ibm1004_ct] = +{ + {0x0152, 0x8c} /* capital ligature oe */, + {0x0153, 0x9c} /* small ligature oe */, + {0x0160, 0x8a} /* capital letter s with caron */, + {0x0161, 0x9a} /* small letter s with caron */, + {0x0178, 0x9f} /* capital letter y with diaeresis */, + {0x02c6, 0x88} /* modificative accent circonflexe */, + {0x02dc, 0x98} /* tilde */, + {0x2013, 0x96} /* dash */, + {0x2014, 0x97} /* dash */, + {0x2018, 0x91} /* single quotation mark */, + {0x2019, 0x92} /* single quotation mark */, + {0x201a, 0x82} /* low-9 quotation mark */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x94} /* double quotation mark */, + {0x201e, 0x84} /* low-9 quotation mark */, + {0x2020, 0x86} /* dagger */, + {0x2021, 0x87} /* dagger */, + {0x2022, 0x95} /* puce */, + {0x2026, 0x85} /* horizontal ellipsis */, + {0x2030, 0x89} /* mille sign */, + {0x2039, 0x8b} /* left-pointing angle quotation mark */, + {0x203a, 0x9b} /* right-pointing angle quotation mark */, + {0x2122, 0x99} /* mark sign */ +}; + +/* +#define cet_ucs4_to_ibm1004_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm1004_extra[cet_ucs4_to_ibm1004_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm1004 = /* defined in cet.h */ +{ + cet_cs_name_ibm1004, /* name of character set */ + cet_cs_alias_ibm1004, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm1004, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm1004, /* first non standard character */ + cet_ucs4_cnt_ibm1004, /* number of values in table */ + + cet_ucs4_to_ibm1004_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm1004_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm1004_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, 0x201a, -1, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, -1, -1, -1, + -1, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, -1, -1, 0x0178, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/ibm1026.h b/cet/ibm1026.h new file mode 100644 index 000000000..18b86c1aa --- /dev/null +++ b/cet/ibm1026.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM1026" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm1026_h +#define ibm1026_h + +#define cet_cs_name_ibm1026 "IBM1026" + +const char *cet_cs_alias_ibm1026[] = +{ + "IBM1026", "1026", "CP1026", NULL +}; + +#define cet_ucs4_ofs_ibm1026 4 +#define cet_ucs4_cnt_ibm1026 252 + +const int cet_ucs4_map_ibm1026[cet_ucs4_cnt_ibm1026] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x007b, 0x00f1, 0x00c7, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x011e, 0x0130, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x005b, 0x00d1, 0x015f, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0131, 0x003a, 0x00d6, + 0x015e, 0x0027, 0x003d, 0x00dc, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x007d, 0x0060, 0x00a6, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x02db, 0x00c6, 0x00a4, 0x00b5, 0x00f6, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x005d, 0x0024, 0x0040, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x2014, 0x00a8, 0x00b4, 0x00d7, 0x00e7, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x007e, 0x00f2, 0x00f3, 0x00f5, 0x011f, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x005c, 0x00f9, 0x00fa, 0x00ff, 0x00fc, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x0023, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x0022, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm1026_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm1026_links[cet_ucs4_to_ibm1026_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0xfc} /* mark */, + {0x0023, 0xec} /* sign */, + {0x0024, 0xad} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xae} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x68} /* square bracket */, + {0x005c, 0xdc} /* solidus */, + {0x005d, 0xac} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x8d} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x48} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x8c} /* curly bracket */, + {0x007e, 0xcc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x8e} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x4a} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0x7b} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0x7f} /* capital letter u with diaeresis */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0xc0} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xa1} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xe0} /* small letter u with diaeresis */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x011e, 0x5a} /* capital letter g with breve */, + {0x011f, 0xd0} /* small letter g with breve */, + {0x0130, 0x5b} /* capital letter i with dot above */, + {0x0131, 0x79} /* small letter i dotless */, + {0x015e, 0x7c} /* capital letter s with cedilla */, + {0x015f, 0x6a} /* small letter s with cedilla */, + {0x02db, 0x9d} /* ogonek */, + {0x2014, 0xbc} /* dash */ +}; + +/* +#define cet_ucs4_to_ibm1026_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm1026_extra[cet_ucs4_to_ibm1026_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm1026 = /* defined in cet.h */ +{ + cet_cs_name_ibm1026, /* name of character set */ + cet_cs_alias_ibm1026, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm1026, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm1026, /* first non standard character */ + cet_ucs4_cnt_ibm1026, /* number of values in table */ + + cet_ucs4_to_ibm1026_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm1026_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm1026_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x007b, 0x00f1, 0x00c7, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x011e, 0x0130, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x005b, 0x00d1, 0x015f, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0131, 0x003a, 0x00d6, 0x015e, 0x0027, 0x003d, 0x00dc, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x007d, 0x0060, 0x00a6, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x02db, 0x00c6, 0x00a4, + 0x00b5, 0x00f6, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x005d, 0x0024, 0x0040, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x2014, 0x00a8, 0x00b4, 0x00d7, + 0x00e7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x007e, 0x00f2, 0x00f3, 0x00f5, + 0x011f, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x005c, 0x00f9, 0x00fa, 0x00ff, + 0x00fc, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x0023, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x0022, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm1047.h b/cet/ibm1047.h new file mode 100644 index 000000000..873d11d3c --- /dev/null +++ b/cet/ibm1047.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM1047" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm1047_h +#define ibm1047_h + +#define cet_cs_name_ibm1047 "IBM1047" + +const char *cet_cs_alias_ibm1047[] = +{ + "IBM1047", "1047", "CP1047", NULL +}; + +#define cet_ucs4_ofs_ibm1047 4 +#define cet_ucs4_cnt_ibm1047 252 + +const int cet_ucs4_map_ibm1047[cet_ucs4_cnt_ibm1047] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00a2, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x0021, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x005b, 0x00de, 0x00ae, 0x00ac, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00dd, 0x00a8, + 0x00af, 0x005d, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm1047_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm1047_links[cet_ucs4_to_ibm1047_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x5a} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xad} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0xbd} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0x4a} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbb} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xb0} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xba} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm1047_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm1047_extra[cet_ucs4_to_ibm1047_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm1047 = /* defined in cet.h */ +{ + cet_cs_name_ibm1047, /* name of character set */ + cet_cs_alias_ibm1047, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm1047, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm1047, /* first non standard character */ + cet_ucs4_cnt_ibm1047, /* number of values in table */ + + cet_ucs4_to_ibm1047_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm1047_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm1047_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00a2, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x0021, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x005b, 0x00de, 0x00ae, + 0x00ac, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00dd, 0x00a8, 0x00af, 0x005d, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm256.h b/cet/ibm256.h new file mode 100644 index 000000000..8603ab569 --- /dev/null +++ b/cet/ibm256.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM256" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm256_h +#define ibm256_h + +#define cet_cs_name_ibm256 "IBM256" + +const char *cet_cs_alias_ibm256[] = +{ + "IBM256", "256", "CP256", "EBCDIC-INT1", + NULL +}; + +#define cet_ucs4_ofs_ibm256 4 +#define cet_ucs4_cnt_ibm256 252 + +const int cet_ucs4_map_ibm256[cet_ucs4_cnt_ibm256] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x005b, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x005d, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x20a7, + 0x0192, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x2017, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x2003, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm256_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm256_links[cet_ucs4_to_ibm256_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x4a} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x5a} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x0192, 0xb4} /* minuscule latine f hameçon */, + {0x2003, 0xe1} /* space */, + {0x2017, 0xbf} /* low line */, + {0x203e, 0xbc} /* overline */, + {0x20a7, 0xb3} /* sign */ +}; + +/* +#define cet_ucs4_to_ibm256_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm256_extra[cet_ucs4_to_ibm256_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm256 = /* defined in cet.h */ +{ + cet_cs_name_ibm256, /* name of character set */ + cet_cs_alias_ibm256, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm256, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm256, /* first non standard character */ + cet_ucs4_cnt_ibm256, /* number of values in table */ + + cet_ucs4_to_ibm256_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm256_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm256_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x005b, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x005d, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x2017, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x2003, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm273.h b/cet/ibm273.h new file mode 100644 index 000000000..63fd4ddd8 --- /dev/null +++ b/cet/ibm273.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM273" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm273_h +#define ibm273_h + +#define cet_cs_name_ibm273 "IBM273" + +const char *cet_cs_alias_ibm273[] = +{ + "IBM273", "273", "CP273", NULL +}; + +#define cet_ucs4_ofs_ibm273 4 +#define cet_ucs4_cnt_ibm273 252 + +const int cet_ucs4_map_ibm273[cet_ucs4_cnt_ibm273] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x007b, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00c4, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x007e, 0x00dc, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x005b, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00f6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x00a7, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x00df, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x0040, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e4, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00a6, 0x00f2, 0x00f3, 0x00f5, 0x00fc, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x007d, 0x00f9, 0x00fa, 0x00ff, 0x00d6, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x005c, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x005d, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm273_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm273_links[cet_ucs4_to_ibm273_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xb5} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x63} /* square bracket */, + {0x005c, 0xec} /* solidus */, + {0x005d, 0xfc} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x43} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0xdc} /* curly bracket */, + {0x007e, 0x59} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xcc} /* bar */, + {0x00a7, 0x7c} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x4a} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xe0} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0x5a} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0xa1} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0xc0} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0x6a} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xd0} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm273_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm273_extra[cet_ucs4_to_ibm273_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm273 = /* defined in cet.h */ +{ + cet_cs_name_ibm273, /* name of character set */ + cet_cs_alias_ibm273, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm273, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm273, /* first non standard character */ + cet_ucs4_cnt_ibm273, /* number of values in table */ + + cet_ucs4_to_ibm273_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm273_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm273_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x007b, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00c4, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x007e, 0x00dc, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x005b, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00f6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x00a7, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x00df, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x0040, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00a6, 0x00f2, 0x00f3, 0x00f5, + 0x00fc, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x007d, 0x00f9, 0x00fa, 0x00ff, + 0x00d6, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x005c, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x005d, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm277.h b/cet/ibm277.h new file mode 100644 index 000000000..c1356e86f --- /dev/null +++ b/cet/ibm277.h @@ -0,0 +1,380 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM277" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm277_h +#define ibm277_h + +#define cet_cs_name_ibm277 "IBM277" + +const char *cet_cs_alias_ibm277[] = +{ + "IBM277", "EBCDIC-CP-DK", "EBCDIC-CP-NO", NULL +}; + +#define cet_ucs4_ofs_ibm277 4 +#define cet_ucs4_cnt_ibm277 252 + +const int cet_ucs4_map_ibm277[cet_ucs4_cnt_ibm277] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x007d, 0x00e7, 0x00f1, 0x0023, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00a4, 0x00c5, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x0024, 0x00c7, 0x00d1, 0x00f8, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00a6, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x00c6, + 0x00d8, 0x0027, 0x003d, 0x0022, 0x0040, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x007b, 0x00b8, 0x005b, 0x005d, 0x00b5, 0x00fc, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e6, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x00e5, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x007e, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm277_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm277_links[cet_ucs4_to_ibm277_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x4a} /* sign */, + {0x0024, 0x67} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x80} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x9e} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x9f} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x9c} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x47} /* curly bracket */, + {0x007e, 0xdc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x5a} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x70} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x5b} /* capital letter a with ring above */, + {0x00c6, 0x7b} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x7c} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0xd0} /* small letter a with ring above */, + {0x00e6, 0xc0} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x6a} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xa1} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm277_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm277_extra[cet_ucs4_to_ibm277_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm277 = /* defined in cet.h */ +{ + cet_cs_name_ibm277, /* name of character set */ + cet_cs_alias_ibm277, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm277, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm277, /* first non standard character */ + cet_ucs4_cnt_ibm277, /* number of values in table */ + + cet_ucs4_to_ibm277_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm277_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm277_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x007d, + 0x00e7, 0x00f1, 0x0023, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00a4, 0x00c5, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x0024, + 0x00c7, 0x00d1, 0x00f8, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00a6, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x00c6, 0x00d8, 0x0027, 0x003d, 0x0022, + 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x007b, 0x00b8, 0x005b, 0x005d, + 0x00b5, 0x00fc, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e6, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x00e5, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x007e, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm278.h b/cet/ibm278.h new file mode 100644 index 000000000..c89719db6 --- /dev/null +++ b/cet/ibm278.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM278" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm278_h +#define ibm278_h + +#define cet_cs_name_ibm278 "IBM278" + +const char *cet_cs_alias_ibm278[] = +{ + "IBM278", "278", "CP278", "ebcdic-cp-fi", + "ebcdic-cp-se", NULL +}; + +#define cet_ucs4_ofs_ibm278 4 +#define cet_ucs4_cnt_ibm278 252 + +const int cet_ucs4_map_ibm278[cet_ucs4_cnt_ibm278] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x007b, + 0x00e0, 0x00e1, 0x00e3, 0x007d, 0x00e7, 0x00f1, 0x00a7, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x0060, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00a4, 0x00c5, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x0023, + 0x00c0, 0x00c1, 0x00c3, 0x0024, 0x00c7, 0x00d1, 0x00f6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00e9, 0x003a, 0x00c4, + 0x00d6, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x005d, 0x00b5, 0x00fc, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x005b, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e4, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00a6, 0x00f2, 0x00f3, 0x00f5, 0x00e5, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x007e, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x0040, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm278_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm278_links[cet_ucs4_to_ibm278_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x63} /* sign */, + {0x0024, 0x67} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xec} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xb5} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x9f} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x51} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x43} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x47} /* curly bracket */, + {0x007e, 0xdc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x5a} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xcc} /* bar */, + {0x00a7, 0x4a} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x7b} /* capital letter a with diaeresis */, + {0x00c5, 0x5b} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0x7c} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0xc0} /* small letter a with diaeresis */, + {0x00e5, 0xd0} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x79} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0x6a} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xa1} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm278_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm278_extra[cet_ucs4_to_ibm278_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm278 = /* defined in cet.h */ +{ + cet_cs_name_ibm278, /* name of character set */ + cet_cs_alias_ibm278, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm278, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm278, /* first non standard character */ + cet_ucs4_cnt_ibm278, /* number of values in table */ + + cet_ucs4_to_ibm278_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm278_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm278_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x007b, 0x00e0, 0x00e1, 0x00e3, 0x007d, + 0x00e7, 0x00f1, 0x00a7, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x0060, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00a4, 0x00c5, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x0023, 0x00c0, 0x00c1, 0x00c3, 0x0024, + 0x00c7, 0x00d1, 0x00f6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00e9, 0x003a, 0x00c4, 0x00d6, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x005d, + 0x00b5, 0x00fc, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x005b, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00a6, 0x00f2, 0x00f3, 0x00f5, + 0x00e5, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x007e, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x0040, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm280.h b/cet/ibm280.h new file mode 100644 index 000000000..da3e7e30d --- /dev/null +++ b/cet/ibm280.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM280" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm280_h +#define ibm280_h + +#define cet_cs_name_ibm280 "IBM280" + +const char *cet_cs_alias_ibm280[] = +{ + "IBM280", "280", "CP280", "ebcdic-cp-it", + NULL +}; + +#define cet_ucs4_ofs_ibm280 4 +#define cet_ucs4_cnt_ibm280 252 + +const int cet_ucs4_map_ibm280[cet_ucs4_cnt_ibm280] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x007b, 0x00e1, 0x00e3, 0x00e5, 0x005c, 0x00f1, 0x00b0, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x005d, 0x00ea, 0x00eb, + 0x007d, 0x00ed, 0x00ee, 0x00ef, 0x007e, 0x00df, 0x00e9, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00f2, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00f9, 0x003a, 0x00a3, + 0x00a7, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x005b, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x00ec, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x0023, 0x00a5, 0x00b7, + 0x00a9, 0x0040, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x00a8, 0x00b4, 0x00d7, 0x00e0, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00a6, 0x00f3, 0x00f5, 0x00e8, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x0060, 0x00fa, 0x00ff, 0x00e7, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm280_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm280_links[cet_ucs4_to_ibm280_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0xb1} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xb5} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x90} /* square bracket */, + {0x005c, 0x48} /* solidus */, + {0x005d, 0x51} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0xdd} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x44} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x54} /* curly bracket */, + {0x007e, 0x58} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0x7b} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xcd} /* bar */, + {0x00a7, 0x7c} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x4a} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0xc0} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0xe0} /* small letter c with cedilla */, + {0x00e8, 0xd0} /* small letter e with grave */, + {0x00e9, 0x5a} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0xa1} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0x6a} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0x79} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm280_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm280_extra[cet_ucs4_to_ibm280_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm280 = /* defined in cet.h */ +{ + cet_cs_name_ibm280, /* name of character set */ + cet_cs_alias_ibm280, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm280, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm280, /* first non standard character */ + cet_ucs4_cnt_ibm280, /* number of values in table */ + + cet_ucs4_to_ibm280_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm280_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm280_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x007b, 0x00e1, 0x00e3, 0x00e5, + 0x005c, 0x00f1, 0x00b0, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x005d, 0x00ea, 0x00eb, 0x007d, 0x00ed, 0x00ee, 0x00ef, + 0x007e, 0x00df, 0x00e9, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00f2, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00f9, 0x003a, 0x00a3, 0x00a7, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x005b, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x00ec, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x0023, 0x00a5, 0x00b7, 0x00a9, 0x0040, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x00a8, 0x00b4, 0x00d7, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00a6, 0x00f3, 0x00f5, + 0x00e8, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x0060, 0x00fa, 0x00ff, + 0x00e7, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm284.h b/cet/ibm284.h new file mode 100644 index 000000000..84e61712f --- /dev/null +++ b/cet/ibm284.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM284" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm284_h +#define ibm284_h + +#define cet_cs_name_ibm284 "IBM284" + +const char *cet_cs_alias_ibm284[] = +{ + "IBM284", "284", "CP284", "ebcdic-cp-es", + NULL +}; + +#define cet_ucs4_ofs_ibm284 4 +#define cet_ucs4_cnt_ibm284 252 + +const int cet_ucs4_map_ibm284[cet_ucs4_cnt_ibm284] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00a6, 0x005b, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x005d, 0x0024, + 0x002a, 0x0029, 0x003b, 0x00ac, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x0023, 0x00f1, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x00d1, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x00a8, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x005e, 0x0021, + 0x203e, 0x007e, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm284_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm284_links[cet_ucs4_to_ibm284_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0xbb} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x69} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x4a} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x5a} /* square bracket */, + {0x005e, 0xba} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xbd} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x49} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xa1} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0x5f} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x7b} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x6a} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm284_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm284_extra[cet_ucs4_to_ibm284_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm284 = /* defined in cet.h */ +{ + cet_cs_name_ibm284, /* name of character set */ + cet_cs_alias_ibm284, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm284, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm284, /* first non standard character */ + cet_ucs4_cnt_ibm284, /* number of values in table */ + + cet_ucs4_to_ibm284_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm284_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm284_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00a6, 0x005b, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x005d, 0x0024, 0x002a, 0x0029, 0x003b, 0x00ac, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x0023, 0x00f1, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x00d1, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x00a8, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x005e, 0x0021, 0x203e, 0x007e, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm285.h b/cet/ibm285.h new file mode 100644 index 000000000..9fbdd32bb --- /dev/null +++ b/cet/ibm285.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM285" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm285_h +#define ibm285_h + +#define cet_cs_name_ibm285 "IBM285" + +const char *cet_cs_alias_ibm285[] = +{ + "IBM285", "285", "CP285", "ebcdic-cp-gb", + NULL +}; + +#define cet_ucs4_ofs_ibm285 4 +#define cet_ucs4_cnt_ibm285 252 + +const int cet_ucs4_map_ibm285[cet_ucs4_cnt_ibm285] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x0024, 0x002e, + 0x003c, 0x0028, 0x002b, 0x007c, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x0021, 0x00a3, + 0x002a, 0x0029, 0x003b, 0x00ac, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x203e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x005b, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x005e, 0x005d, + 0x007e, 0x00a8, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm285_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm285_links[cet_ucs4_to_ibm285_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x5a} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x4a} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xb1} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0xbb} /* square bracket */, + {0x005e, 0xba} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0x4f} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xbc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0x5b} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0x5f} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xa1} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm285_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm285_extra[cet_ucs4_to_ibm285_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm285 = /* defined in cet.h */ +{ + cet_cs_name_ibm285, /* name of character set */ + cet_cs_alias_ibm285, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm285, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm285, /* first non standard character */ + cet_ucs4_cnt_ibm285, /* number of values in table */ + + cet_ucs4_to_ibm285_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm285_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm285_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x0024, 0x002e, 0x003c, 0x0028, 0x002b, 0x007c, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x0021, 0x00a3, 0x002a, 0x0029, 0x003b, 0x00ac, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x203e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x005b, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x005e, 0x005d, 0x007e, 0x00a8, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm297.h b/cet/ibm297.h new file mode 100644 index 000000000..9b327eee5 --- /dev/null +++ b/cet/ibm297.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM297" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm297_h +#define ibm297_h + +#define cet_cs_name_ibm297 "IBM297" + +const char *cet_cs_alias_ibm297[] = +{ + "IBM297", "297", "CP297", "ebcdic-cp-fr", + NULL +}; + +#define cet_ucs4_ofs_ibm297 4 +#define cet_ucs4_cnt_ibm297 252 + +const int cet_ucs4_map_ibm297[cet_ucs4_cnt_ibm297] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x0040, 0x00e1, 0x00e3, 0x00e5, 0x005c, 0x00f1, 0x00b0, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x007b, 0x00ea, 0x00eb, + 0x007d, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00a7, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00f9, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00b5, 0x003a, 0x00a3, + 0x00e0, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x005b, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x0060, 0x00a8, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x0023, 0x00a5, 0x00b7, + 0x00a9, 0x005d, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x203e, 0x007e, 0x00b4, 0x00d7, 0x00e9, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x00e8, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00a6, 0x00fa, 0x00ff, 0x00e7, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm297_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm297_links[cet_ucs4_to_ibm297_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0xb1} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x44} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x90} /* square bracket */, + {0x005c, 0x48} /* solidus */, + {0x005d, 0xb5} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0xa0} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x51} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x54} /* curly bracket */, + {0x007e, 0xbd} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0x7b} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0xdd} /* bar */, + {0x00a7, 0x5a} /* sign */, + {0x00a8, 0xa1} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00b0, 0x4a} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0x79} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x7c} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0xe0} /* small letter c with cedilla */, + {0x00e8, 0xd0} /* small letter e with grave */, + {0x00e9, 0xc0} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0x6a} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */, + {0x203e, 0xbc} /* overline */ +}; + +/* +#define cet_ucs4_to_ibm297_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm297_extra[cet_ucs4_to_ibm297_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm297 = /* defined in cet.h */ +{ + cet_cs_name_ibm297, /* name of character set */ + cet_cs_alias_ibm297, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm297, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm297, /* first non standard character */ + cet_ucs4_cnt_ibm297, /* number of values in table */ + + cet_ucs4_to_ibm297_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm297_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm297_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x0040, 0x00e1, 0x00e3, 0x00e5, + 0x005c, 0x00f1, 0x00b0, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x007b, 0x00ea, 0x00eb, 0x007d, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00a7, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00f9, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00b5, 0x003a, 0x00a3, 0x00e0, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x005b, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x0060, 0x00a8, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x0023, 0x00a5, 0x00b7, 0x00a9, 0x005d, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x203e, 0x007e, 0x00b4, 0x00d7, + 0x00e9, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x00e8, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00a6, 0x00fa, 0x00ff, + 0x00e7, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm437.h b/cet/ibm437.h new file mode 100644 index 000000000..7c0520ea8 --- /dev/null +++ b/cet/ibm437.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM437" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm437_h +#define ibm437_h + +#define cet_cs_name_ibm437 "IBM437" + +const char *cet_cs_alias_ibm437[] = +{ + "IBM437", "437", "CP437", NULL +}; + +#define cet_ucs4_ofs_ibm437 128 +#define cet_ucs4_cnt_ibm437 128 + +const int cet_ucs4_map_ibm437[cet_ucs4_cnt_ibm437] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm437_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm437_links[cet_ucs4_to_ibm437_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a5, 0x9d} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm437_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm437_extra[cet_ucs4_to_ibm437_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm437 = /* defined in cet.h */ +{ + cet_cs_name_ibm437, /* name of character set */ + cet_cs_alias_ibm437, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm437, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm437, /* first non standard character */ + cet_ucs4_cnt_ibm437, /* number of values in table */ + + cet_ucs4_to_ibm437_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm437_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm437_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm500.h b/cet/ibm500.h new file mode 100644 index 000000000..8d64499a0 --- /dev/null +++ b/cet/ibm500.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM500" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm500_h +#define ibm500_h + +#define cet_cs_name_ibm500 "IBM500" + +const char *cet_cs_alias_ibm500[] = +{ + "IBM500", "500", "500V1", "CP500", + "ebcdic-cp-be", "ebcdic-cp-ch", NULL +}; + +#define cet_ucs4_ofs_ibm500 4 +#define cet_ucs4_cnt_ibm500 252 + +const int cet_ucs4_map_ibm500[cet_ucs4_cnt_ibm500] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x005b, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x005d, 0x0024, + 0x002a, 0x0029, 0x003b, 0x005e, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x0060, 0x003a, 0x0023, + 0x0040, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x00f0, 0x00fd, 0x00fe, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x00e6, 0x00b8, 0x00c6, 0x00a4, 0x00b5, 0x007e, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x00d0, 0x00dd, 0x00de, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x00af, 0x00a8, 0x00b4, 0x00d7, 0x007b, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x00f6, 0x00f2, 0x00f3, 0x00f5, 0x007d, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x005c, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x00d6, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm500_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm500_links[cet_ucs4_to_ibm500_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0x7c} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0x4a} /* square bracket */, + {0x005c, 0xe0} /* solidus */, + {0x005d, 0x5a} /* square bracket */, + {0x005e, 0x5f} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x79} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0xc0} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0xd0} /* curly bracket */, + {0x007e, 0xa1} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xbe} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x9e} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0xac} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0xec} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xae} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0x9c} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xcc} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x8e} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm500_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm500_extra[cet_ucs4_to_ibm500_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm500 = /* defined in cet.h */ +{ + cet_cs_name_ibm500, /* name of character set */ + cet_cs_alias_ibm500, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm500, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm500, /* first non standard character */ + cet_ucs4_cnt_ibm500, /* number of values in table */ + + cet_ucs4_to_ibm500_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm500_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm500_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x005b, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x005d, 0x0024, 0x002a, 0x0029, 0x003b, 0x005e, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x0060, 0x003a, 0x0023, 0x0040, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x00f0, 0x00fd, 0x00fe, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x00e6, 0x00b8, 0x00c6, 0x00a4, + 0x00b5, 0x007e, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x00d0, 0x00dd, 0x00de, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x00af, 0x00a8, 0x00b4, 0x00d7, + 0x007b, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x00f6, 0x00f2, 0x00f3, 0x00f5, + 0x007d, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x005c, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x00d6, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm850.h b/cet/ibm850.h new file mode 100644 index 000000000..cb4e04ad5 --- /dev/null +++ b/cet/ibm850.h @@ -0,0 +1,257 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM850" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm850_h +#define ibm850_h + +#define cet_cs_name_ibm850 "IBM850" + +const char *cet_cs_alias_ibm850[] = +{ + "IBM850", "850", "CP850", "csPC850Multilingual", + NULL +}; + +#define cet_ucs4_ofs_ibm850 128 +#define cet_ucs4_cnt_ibm850 128 + +const int cet_ucs4_map_ibm850[cet_ucs4_cnt_ibm850] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, + 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm850_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm850_links[cet_ucs4_to_ibm850_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0xbd} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a4, 0xcf} /* sign */, + {0x00a5, 0xbe} /* sign */, + {0x00a6, 0xdd} /* bar */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00a9, 0xb8} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00ae, 0xa9} /* sign */, + {0x00af, 0xee} /* macron */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xfc} /* three */, + {0x00b4, 0xef} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0xf4} /* sign */, + {0x00b7, 0xfa} /* dot */, + {0x00b8, 0xf7} /* cedilla */, + {0x00b9, 0xfb} /* one */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00be, 0xf3} /* fraction three quarters */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0xb7} /* capital letter a with grave */, + {0x00c1, 0xb5} /* capital letter a with acute */, + {0x00c2, 0xb6} /* capital letter a with circumflex */, + {0x00c3, 0xc7} /* capital letter a with tilde */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0xd4} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0xd2} /* capital letter e with circumflex */, + {0x00cb, 0xd3} /* capital letter e with diaeresis */, + {0x00cc, 0xde} /* capital letter i with grave */, + {0x00cd, 0xd6} /* capital letter i with acute */, + {0x00ce, 0xd7} /* capital letter i with circumflex */, + {0x00cf, 0xd8} /* capital letter i with diaeresis */, + {0x00d0, 0xd1} /* capital letter eth (icelandic) */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0xe3} /* capital letter o with grave */, + {0x00d3, 0xe0} /* capital letter o with acute */, + {0x00d4, 0xe2} /* capital letter o with circumflex */, + {0x00d5, 0xe5} /* capital letter o with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d7, 0x9e} /* sign */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00d9, 0xeb} /* capital letter u with grave */, + {0x00da, 0xe9} /* capital letter u with acute */, + {0x00db, 0xea} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0xed} /* capital letter y with acute */, + {0x00de, 0xe8} /* capital letter thorn (icelandic) */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0xc6} /* small letter a with tilde */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f0, 0xd0} /* small letter eth (icelandic) */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0xe4} /* small letter o with tilde */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0xec} /* small letter y with acute */, + {0x00fe, 0xe7} /* small letter thorn (icelandic) */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0131, 0xd5} /* small letter i dotless */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x2017, 0xf2} /* low line */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm850_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm850_extra[cet_ucs4_to_ibm850_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm850 = /* defined in cet.h */ +{ + cet_cs_name_ibm850, /* name of character set */ + cet_cs_alias_ibm850, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm850, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm850, /* first non standard character */ + cet_ucs4_cnt_ibm850, /* number of values in table */ + + cet_ucs4_to_ibm850_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm850_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm850_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, + 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm851.h b/cet/ibm851.h new file mode 100644 index 000000000..95bab532c --- /dev/null +++ b/cet/ibm851.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM851" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm851_h +#define ibm851_h + +#define cet_cs_name_ibm851 "IBM851" + +const char *cet_cs_alias_ibm851[] = +{ + "IBM851", "851", "CP851", NULL +}; + +#define cet_ucs4_ofs_ibm851 128 +#define cet_ucs4_cnt_ibm851 128 + +const int cet_ucs4_map_ibm851[cet_ucs4_cnt_ibm851] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x0386, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0388, 0x00c4, 0x0389, + 0x038a, -1, 0x038c, 0x00f4, 0x00f6, 0x038e, 0x00fb, 0x00f9, + 0x038f, 0x00d6, 0x00dc, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039d, + 0x039c, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x02db, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm851_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm851_links[cet_ucs4_to_ibm851_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a3, 0x9c} /* sign */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b4, 0xef} /* accent */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bd, 0xab} /* fraction one half */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x02db, 0xf7} /* ogonek */, + {0x0386, 0x86} /* capital letter alpha with acute */, + {0x0388, 0x8d} /* capital letter epsilon with acute */, + {0x0389, 0x8f} /* capital letter eta with acute */, + {0x038a, 0x90} /* capital letter iota with acute */, + {0x038c, 0x92} /* capital letter omicron with acute */, + {0x038e, 0x95} /* capital letter upsilon with acute */, + {0x038f, 0x98} /* capital letter omega with acute */, + {0x0390, 0xa1} /* small letter iota with acute and diaeresis */, + {0x0391, 0xa4} /* capital letter alpha */, + {0x0392, 0xa5} /* capital letter beta */, + {0x0393, 0xa6} /* capital letter gamma */, + {0x0394, 0xa7} /* capital letter delta */, + {0x0395, 0xa8} /* capital letter epsilon */, + {0x0396, 0xa9} /* capital letter zeta */, + {0x0397, 0xaa} /* capital letter eta */, + {0x0398, 0xac} /* capital letter theta */, + {0x0399, 0xad} /* capital letter iota */, + {0x039a, 0xb5} /* capital letter kappa */, + {0x039b, 0xb6} /* capital letter lamda */, + {0x039c, 0xb8} /* capital letter mu */, + {0x039d, 0xb7} /* capital letter nu */, + {0x039e, 0xbd} /* capital letter xi */, + {0x039f, 0xbe} /* capital letter omicron */, + {0x03a0, 0xc6} /* capital letter pi */, + {0x03a1, 0xc7} /* capital letter rho */, + {0x03a3, 0xcf} /* capital letter sigma */, + {0x03a4, 0xd0} /* capital letter tau */, + {0x03a5, 0xd1} /* capital letter upsilon */, + {0x03a6, 0xd2} /* capital letter phi */, + {0x03a7, 0xd3} /* capital letter chi */, + {0x03a8, 0xd4} /* capital letter psi */, + {0x03a9, 0xd5} /* capital letter omega */, + {0x03ac, 0x9b} /* small letter alpha with acute */, + {0x03ad, 0x9d} /* small letter epsilon with acute */, + {0x03ae, 0x9e} /* small letter eta with acute */, + {0x03af, 0x9f} /* small letter iota with acute */, + {0x03b0, 0xfc} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xd6} /* small letter alpha */, + {0x03b2, 0xd7} /* small letter beta */, + {0x03b3, 0xd8} /* small letter gamma */, + {0x03b4, 0xdd} /* small letter delta */, + {0x03b5, 0xde} /* small letter epsilon */, + {0x03b6, 0xe0} /* small letter zeta */, + {0x03b7, 0xe1} /* small letter eta */, + {0x03b8, 0xe2} /* small letter theta */, + {0x03b9, 0xe3} /* small letter iota */, + {0x03ba, 0xe4} /* small letter kappa */, + {0x03bb, 0xe5} /* small letter lamda */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03bd, 0xe7} /* small letter nu */, + {0x03be, 0xe8} /* small letter xi */, + {0x03bf, 0xe9} /* small letter omicron */, + {0x03c0, 0xea} /* small letter pi */, + {0x03c1, 0xeb} /* small letter rho */, + {0x03c2, 0xed} /* small letter final sigma */, + {0x03c3, 0xec} /* small letter sigma */, + {0x03c4, 0xee} /* small letter tau */, + {0x03c5, 0xf2} /* small letter upsilon */, + {0x03c6, 0xf3} /* small letter phi */, + {0x03c7, 0xf4} /* small letter chi */, + {0x03c8, 0xf6} /* small letter psi */, + {0x03c9, 0xfa} /* small letter omega */, + {0x03ca, 0xa0} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xa2} /* small letter omicron with acute */, + {0x03cd, 0xa3} /* small letter upsilon with acute */, + {0x03ce, 0xfd} /* small letter omega with acute */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm851_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm851_extra[cet_ucs4_to_ibm851_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm851 = /* defined in cet.h */ +{ + cet_cs_name_ibm851, /* name of character set */ + cet_cs_alias_ibm851, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm851, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm851, /* first non standard character */ + cet_ucs4_cnt_ibm851, /* number of values in table */ + + cet_ucs4_to_ibm851_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm851_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm851_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x0386, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0388, 0x00c4, 0x0389, + 0x038a, -1, 0x038c, 0x00f4, 0x00f6, 0x038e, 0x00fb, 0x00f9, + 0x038f, 0x00d6, 0x00dc, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039d, + 0x039c, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x02db, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm852.h b/cet/ibm852.h new file mode 100644 index 000000000..8332c19c3 --- /dev/null +++ b/cet/ibm852.h @@ -0,0 +1,257 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM852" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm852_h +#define ibm852_h + +#define cet_cs_name_ibm852 "IBM852" + +const char *cet_cs_alias_ibm852[] = +{ + "IBM852", "852", "CP852", "pcl2", + "pclatin2", NULL +}; + +#define cet_ucs4_ofs_ibm852 128 +#define cet_ucs4_cnt_ibm852 128 + +const int cet_ucs4_map_ibm852[cet_ucs4_cnt_ibm852] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x016f, 0x0107, 0x00e7, + 0x0142, 0x00eb, 0x0150, 0x0151, 0x00ee, 0x0179, 0x00c4, 0x0106, + 0x00c9, 0x0139, 0x013a, 0x00f4, 0x00f6, 0x013d, 0x013e, 0x015a, + 0x015b, 0x00d6, 0x00dc, 0x0164, 0x0165, 0x0141, 0x00d7, 0x010d, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0104, 0x0105, 0x017d, 0x017e, + 0x0118, 0x0119, 0x00ac, 0x017a, 0x010c, 0x015f, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x011a, + 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0102, 0x0103, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x0111, 0x0110, 0x010e, 0x00cb, 0x010f, 0x0147, 0x00cd, 0x00ce, + 0x011b, 0x2518, 0x250c, 0x2588, 0x2584, 0x0162, 0x016e, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00da, 0x0155, 0x0170, 0x00fd, 0x00dd, 0x0163, 0x00b4, + 0x00ad, 0x02dd, 0x02db, 0x02c7, 0x02d8, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x02d9, 0x0171, 0x0158, 0x0159, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm852_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm852_links[cet_ucs4_to_ibm852_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a4, 0xcf} /* sign */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b0, 0xf8} /* sign */, + {0x00b4, 0xef} /* accent */, + {0x00b8, 0xf7} /* cedilla */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00c1, 0xb5} /* capital letter a with acute */, + {0x00c2, 0xb6} /* capital letter a with circumflex */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cb, 0xd3} /* capital letter e with diaeresis */, + {0x00cd, 0xd6} /* capital letter i with acute */, + {0x00ce, 0xd7} /* capital letter i with circumflex */, + {0x00d3, 0xe0} /* capital letter o with acute */, + {0x00d4, 0xe2} /* capital letter o with circumflex */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d7, 0x9e} /* sign */, + {0x00da, 0xe9} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0xed} /* capital letter y with acute */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0xec} /* small letter y with acute */, + {0x0102, 0xc6} /* capital letter a with breve */, + {0x0103, 0xc7} /* small letter a with breve */, + {0x0104, 0xa4} /* capital letter a with ogonek */, + {0x0105, 0xa5} /* small letter a with ogonek */, + {0x0106, 0x8f} /* capital letter c with acute */, + {0x0107, 0x86} /* small letter c with acute */, + {0x010c, 0xac} /* capital letter c with caron */, + {0x010d, 0x9f} /* small letter c with caron */, + {0x010e, 0xd2} /* capital letter d with caron */, + {0x010f, 0xd4} /* small letter d with caron */, + {0x0110, 0xd1} /* capital letter d with stroke */, + {0x0111, 0xd0} /* small letter d with stroke */, + {0x0118, 0xa8} /* capital letter e with ogonek */, + {0x0119, 0xa9} /* small letter e with ogonek */, + {0x011a, 0xb7} /* capital letter e with caron */, + {0x011b, 0xd8} /* small letter e with caron */, + {0x0139, 0x91} /* capital letter l with acute */, + {0x013a, 0x92} /* small letter l with acute */, + {0x013d, 0x95} /* capital letter l with caron */, + {0x013e, 0x96} /* small letter l with caron */, + {0x0141, 0x9d} /* capital letter l with stroke */, + {0x0142, 0x88} /* small letter l with stroke */, + {0x0143, 0xe3} /* capital letter n with acute */, + {0x0144, 0xe4} /* small letter n with acute */, + {0x0147, 0xd5} /* capital letter n with caron */, + {0x0148, 0xe5} /* small letter n with caron */, + {0x0150, 0x8a} /* capital letter o with double acute */, + {0x0151, 0x8b} /* small letter o with double acute */, + {0x0154, 0xe8} /* capital letter r with acute */, + {0x0155, 0xea} /* small letter r with acute */, + {0x0158, 0xfc} /* capital letter r with caron */, + {0x0159, 0xfd} /* small letter r with caron */, + {0x015a, 0x97} /* capital letter s with acute */, + {0x015b, 0x98} /* small letter s with acute */, + {0x015e, 0xb8} /* capital letter s with cedilla */, + {0x015f, 0xad} /* small letter s with cedilla */, + {0x0160, 0xe6} /* capital letter s with caron */, + {0x0161, 0xe7} /* small letter s with caron */, + {0x0162, 0xdd} /* capital letter t with cedilla */, + {0x0163, 0xee} /* small letter t with cedilla */, + {0x0164, 0x9b} /* capital letter t with caron */, + {0x0165, 0x9c} /* small letter t with caron */, + {0x016e, 0xde} /* capital letter u with ring above */, + {0x016f, 0x85} /* small letter u with ring above */, + {0x0170, 0xeb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0x8d} /* capital letter z with acute */, + {0x017a, 0xab} /* small letter z with acute */, + {0x017b, 0xbd} /* capital letter z with dot above */, + {0x017c, 0xbe} /* small letter z with dot above */, + {0x017d, 0xa6} /* capital letter z with caron */, + {0x017e, 0xa7} /* small letter z with caron */, + {0x02c7, 0xf3} /* caron */, + {0x02d8, 0xf4} /* breve */, + {0x02d9, 0xfa} /* above */, + {0x02db, 0xf2} /* ogonek */, + {0x02dd, 0xf1} /* acute accent */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm852_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm852_extra[cet_ucs4_to_ibm852_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm852 = /* defined in cet.h */ +{ + cet_cs_name_ibm852, /* name of character set */ + cet_cs_alias_ibm852, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm852, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm852, /* first non standard character */ + cet_ucs4_cnt_ibm852, /* number of values in table */ + + cet_ucs4_to_ibm852_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm852_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm852_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x016f, 0x0107, 0x00e7, + 0x0142, 0x00eb, 0x0150, 0x0151, 0x00ee, 0x0179, 0x00c4, 0x0106, + 0x00c9, 0x0139, 0x013a, 0x00f4, 0x00f6, 0x013d, 0x013e, 0x015a, + 0x015b, 0x00d6, 0x00dc, 0x0164, 0x0165, 0x0141, 0x00d7, 0x010d, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0104, 0x0105, 0x017d, 0x017e, + 0x0118, 0x0119, 0x00ac, 0x017a, 0x010c, 0x015f, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x011a, + 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0102, 0x0103, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x0111, 0x0110, 0x010e, 0x00cb, 0x010f, 0x0147, 0x00cd, 0x00ce, + 0x011b, 0x2518, 0x250c, 0x2588, 0x2584, 0x0162, 0x016e, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00da, 0x0155, 0x0170, 0x00fd, 0x00dd, 0x0163, 0x00b4, + 0x00ad, 0x02dd, 0x02db, 0x02c7, 0x02d8, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x02d9, 0x0171, 0x0158, 0x0159, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm855.h b/cet/ibm855.h new file mode 100644 index 000000000..4ed6603e8 --- /dev/null +++ b/cet/ibm855.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM855" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm855_h +#define ibm855_h + +#define cet_cs_name_ibm855 "IBM855" + +const char *cet_cs_alias_ibm855[] = +{ + "IBM855", "855", "CP855", NULL +}; + +#define cet_ucs4_ofs_ibm855 128 +#define cet_ucs4_cnt_ibm855 128 + +const int cet_ucs4_map_ibm855[cet_ucs4_cnt_ibm855] = +{ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045a, 0x040a, 0x045b, 0x0093, 0x045c, 0x040c, + 0x045e, 0x040e, 0x045f, 0x040f, 0x044e, 0x042e, 0x044a, 0x042a, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255d, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x043a, 0x041a, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x043b, 0x041b, 0x043c, 0x041c, 0x043d, 0x041d, 0x043e, 0x041e, + 0x043f, 0x2518, 0x250c, 0x2588, 0x2584, 0x041f, 0x044f, 0x2580, + 0x042f, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044c, 0x042c, 0x00b4, + 0x00ad, 0x044b, 0x042b, 0x0437, 0x0417, 0x0448, 0x0428, 0x044d, + 0x042d, 0x0449, 0x0429, 0x0447, 0x0427, -1, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm855_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm855_links[cet_ucs4_to_ibm855_ct] = +{ + {0x0093, 0x95} /* transmit state (sts) */, + {0x00a0, 0xff} /* space */, + {0x00a4, 0xcf} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b4, 0xef} /* accent */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x0401, 0x85} /* capital letter io */, + {0x0402, 0x81} /* capital letter dje (serbocroatian) */, + {0x0403, 0x83} /* capital letter gje (macedonian) */, + {0x0404, 0x87} /* capital letter ukrainian ie */, + {0x0405, 0x89} /* capital letter dze (macedonian) */, + {0x0406, 0x8b} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0x8d} /* capital letter yi (ukrainian) */, + {0x0408, 0x8f} /* capital letter je */, + {0x0409, 0x91} /* capital letter lje */, + {0x040a, 0x93} /* capital letter nje */, + {0x040c, 0x97} /* capital letter kje (macedonian) */, + {0x040e, 0x99} /* capital letter short u (byelorussian) */, + {0x040f, 0x9b} /* capital letter dzhe */, + {0x0410, 0xa1} /* capital letter a */, + {0x0411, 0xa3} /* capital letter be */, + {0x0412, 0xec} /* capital letter ve */, + {0x0413, 0xad} /* capital letter ghe */, + {0x0414, 0xa7} /* capital letter de */, + {0x0415, 0xa9} /* capital letter ie */, + {0x0416, 0xea} /* capital letter zhe */, + {0x0417, 0xf4} /* capital letter ze */, + {0x0418, 0xb8} /* capital letter i */, + {0x0419, 0xbe} /* capital letter short i */, + {0x041a, 0xc7} /* capital letter ka */, + {0x041b, 0xd1} /* capital letter el */, + {0x041c, 0xd3} /* capital letter em */, + {0x041d, 0xd5} /* capital letter en */, + {0x041e, 0xd7} /* capital letter o */, + {0x041f, 0xdd} /* capital letter pe */, + {0x0420, 0xe2} /* capital letter er */, + {0x0421, 0xe4} /* capital letter es */, + {0x0422, 0xe6} /* capital letter te */, + {0x0423, 0xe8} /* capital letter u */, + {0x0424, 0xab} /* capital letter ef */, + {0x0425, 0xb6} /* capital letter ha */, + {0x0426, 0xa5} /* capital letter tse */, + {0x0427, 0xfc} /* capital letter che */, + {0x0428, 0xf6} /* capital letter sha */, + {0x0429, 0xfa} /* capital letter shcha */, + {0x042a, 0x9f} /* capital letter hard sign */, + {0x042b, 0xf2} /* capital letter yeru */, + {0x042c, 0xee} /* capital letter soft sign */, + {0x042d, 0xf8} /* capital letter e */, + {0x042e, 0x9d} /* capital letter yu */, + {0x042f, 0xe0} /* capital letter ya */, + {0x0430, 0xa0} /* small letter a */, + {0x0431, 0xa2} /* small letter be */, + {0x0432, 0xeb} /* small letter ve */, + {0x0433, 0xac} /* small letter ghe */, + {0x0434, 0xa6} /* small letter de */, + {0x0435, 0xa8} /* small letter ie */, + {0x0436, 0xe9} /* small letter zhe */, + {0x0437, 0xf3} /* small letter ze */, + {0x0438, 0xb7} /* small letter i */, + {0x0439, 0xbd} /* small letter short i */, + {0x043a, 0xc6} /* small letter ka */, + {0x043b, 0xd0} /* small letter el */, + {0x043c, 0xd2} /* small letter em */, + {0x043d, 0xd4} /* small letter en */, + {0x043e, 0xd6} /* small letter o */, + {0x043f, 0xd8} /* small letter pe */, + {0x0440, 0xe1} /* small letter er */, + {0x0441, 0xe3} /* small letter es */, + {0x0442, 0xe5} /* small letter te */, + {0x0443, 0xe7} /* small letter u */, + {0x0444, 0xaa} /* small letter ef */, + {0x0445, 0xb5} /* small letter ha */, + {0x0446, 0xa4} /* small letter tse */, + {0x0447, 0xfb} /* small letter che */, + {0x0448, 0xf5} /* small letter sha */, + {0x0449, 0xf9} /* small letter shcha */, + {0x044a, 0x9e} /* small letter hard sign */, + {0x044b, 0xf1} /* small letter yeru */, + {0x044c, 0xed} /* small letter soft sign */, + {0x044d, 0xf7} /* small letter e */, + {0x044e, 0x9c} /* small letter yu */, + {0x044f, 0xde} /* small letter ya */, + {0x0451, 0x84} /* small letter io */, + {0x0452, 0x80} /* small letter dje (serbocroatian) */, + {0x0453, 0x82} /* small letter gje (macedonian) */, + {0x0454, 0x86} /* small letter ukrainian ie */, + {0x0455, 0x88} /* small letter dze (macedonian) */, + {0x0456, 0x8a} /* small letter byelorussian-ukrainian i */, + {0x0457, 0x8c} /* small letter yi (ukrainian) */, + {0x0458, 0x8e} /* small letter je */, + {0x0459, 0x90} /* small letter lje */, + {0x045a, 0x92} /* small letter nje */, + {0x045b, 0x94} /* small letter tshe (serbocroatian) */, + {0x045c, 0x96} /* small letter kje (macedonian) */, + {0x045e, 0x98} /* small letter short u (byelorussian) */, + {0x045f, 0x9a} /* small letter dzhe */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm855_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm855_extra[cet_ucs4_to_ibm855_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm855 = /* defined in cet.h */ +{ + cet_cs_name_ibm855, /* name of character set */ + cet_cs_alias_ibm855, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm855, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm855, /* first non standard character */ + cet_ucs4_cnt_ibm855, /* number of values in table */ + + cet_ucs4_to_ibm855_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm855_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm855_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045a, 0x040a, 0x045b, 0x0093, 0x045c, 0x040c, + 0x045e, 0x040e, 0x045f, 0x040f, 0x044e, 0x042e, 0x044a, 0x042a, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255d, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x043a, 0x041a, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x043b, 0x041b, 0x043c, 0x041c, 0x043d, 0x041d, 0x043e, 0x041e, + 0x043f, 0x2518, 0x250c, 0x2588, 0x2584, 0x041f, 0x044f, 0x2580, + 0x042f, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044c, 0x042c, 0x00b4, + 0x00ad, 0x044b, 0x042b, 0x0437, 0x0417, 0x0448, 0x0428, 0x044d, + 0x042d, 0x0449, 0x0429, 0x0447, 0x0427, -1, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm857.h b/cet/ibm857.h new file mode 100644 index 000000000..4b26cdb28 --- /dev/null +++ b/cet/ibm857.h @@ -0,0 +1,252 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM857" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm857_h +#define ibm857_h + +#define cet_cs_name_ibm857 "IBM857" + +const char *cet_cs_alias_ibm857[] = +{ + "IBM857", "857", "CP857", NULL +}; + +#define cet_ucs4_ofs_ibm857 128 +#define cet_ucs4_cnt_ibm857 128 + +const int cet_ucs4_map_ibm857[cet_ucs4_cnt_ibm857] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0131, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x0130, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x015e, 0x015f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00ba, 0x00aa, 0x00ca, 0x00cb, 0x00c8, -1, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, -1, + 0x00d7, 0x00da, 0x00db, 0x00d9, 0x00ec, 0x00ff, 0x2014, 0x00b4, + 0x00ad, 0x00b1, -1, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x02db, + 0x00b0, 0x00a8, 0x02d9, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm857_ct 124 + +const cet_ucs4_link_t cet_ucs4_to_ibm857_links[cet_ucs4_to_ibm857_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0xbd} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a4, 0xcf} /* sign */, + {0x00a5, 0xbe} /* sign */, + {0x00a6, 0xdd} /* bar */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00a9, 0xb8} /* sign */, + {0x00aa, 0xd1} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00ae, 0xa9} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xfc} /* three */, + {0x00b4, 0xef} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0xf4} /* sign */, + {0x00b9, 0xfb} /* one */, + {0x00ba, 0xd0} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00be, 0xf3} /* fraction three quarters */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0xb7} /* capital letter a with grave */, + {0x00c1, 0xb5} /* capital letter a with acute */, + {0x00c2, 0xb6} /* capital letter a with circumflex */, + {0x00c3, 0xc7} /* capital letter a with tilde */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0xd4} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0xd2} /* capital letter e with circumflex */, + {0x00cb, 0xd3} /* capital letter e with diaeresis */, + {0x00cc, 0xde} /* capital letter i with grave */, + {0x00cd, 0xd6} /* capital letter i with acute */, + {0x00ce, 0xd7} /* capital letter i with circumflex */, + {0x00cf, 0xd8} /* capital letter i with diaeresis */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0xe3} /* capital letter o with grave */, + {0x00d3, 0xe0} /* capital letter o with acute */, + {0x00d4, 0xe2} /* capital letter o with circumflex */, + {0x00d5, 0xe5} /* capital letter o with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d7, 0xe8} /* sign */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00d9, 0xeb} /* capital letter u with grave */, + {0x00da, 0xe9} /* capital letter u with acute */, + {0x00db, 0xea} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0xc6} /* small letter a with tilde */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0xe4} /* small letter o with tilde */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0xed} /* small letter y with diaeresis */, + {0x011e, 0xa6} /* capital letter g with breve */, + {0x011f, 0xa7} /* small letter g with breve */, + {0x0130, 0x98} /* capital letter i with dot above */, + {0x0131, 0x8d} /* small letter i dotless */, + {0x015e, 0x9e} /* capital letter s with cedilla */, + {0x015f, 0x9f} /* small letter s with cedilla */, + {0x02d9, 0xfa} /* above */, + {0x02db, 0xf7} /* ogonek */, + {0x2014, 0xee} /* dash */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm857_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm857_extra[cet_ucs4_to_ibm857_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm857 = /* defined in cet.h */ +{ + cet_cs_name_ibm857, /* name of character set */ + cet_cs_alias_ibm857, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm857, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm857, /* first non standard character */ + cet_ucs4_cnt_ibm857, /* number of values in table */ + + cet_ucs4_to_ibm857_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm857_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm857_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0131, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x0130, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x015e, 0x015f, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + 0x00ba, 0x00aa, 0x00ca, 0x00cb, 0x00c8, -1, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, -1, + 0x00d7, 0x00da, 0x00db, 0x00d9, 0x00ec, 0x00ff, 0x2014, 0x00b4, + 0x00ad, 0x00b1, -1, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x02db, + 0x00b0, 0x00a8, 0x02d9, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm860.h b/cet/ibm860.h new file mode 100644 index 000000000..c2d2ced62 --- /dev/null +++ b/cet/ibm860.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM860" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm860_h +#define ibm860_h + +#define cet_cs_name_ibm860 "IBM860" + +const char *cet_cs_alias_ibm860[] = +{ + "IBM860", "860", "CP860", NULL +}; + +#define cet_ucs4_ofs_ibm860 128 +#define cet_ucs4_cnt_ibm860 128 + +const int cet_ucs4_map_ibm860[cet_ucs4_cnt_ibm860] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e3, 0x00e0, 0x00c1, 0x00e7, + 0x00ea, 0x00ca, 0x00e8, 0x00ce, 0x00d4, 0x00ec, 0x00c3, 0x00c2, + 0x00c9, 0x00c0, 0x00c8, 0x00f4, 0x00f5, 0x00f2, 0x00da, 0x00f9, + 0x00cc, 0x00d5, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00d3, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm860_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm860_links[cet_ucs4_to_ibm860_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c0, 0x91} /* capital letter a with grave */, + {0x00c1, 0x86} /* capital letter a with acute */, + {0x00c2, 0x8f} /* capital letter a with circumflex */, + {0x00c3, 0x8e} /* capital letter a with tilde */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0x92} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0x89} /* capital letter e with circumflex */, + {0x00cc, 0x98} /* capital letter i with grave */, + {0x00ce, 0x8b} /* capital letter i with circumflex */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0x9f} /* capital letter o with grave */, + {0x00d3, 0xa9} /* capital letter o with acute */, + {0x00d4, 0x8c} /* capital letter o with circumflex */, + {0x00d5, 0x99} /* capital letter o with tilde */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00da, 0x96} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e3, 0x84} /* small letter a with tilde */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f5, 0x94} /* small letter o with tilde */, + {0x00f7, 0xf6} /* sign */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm860_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm860_extra[cet_ucs4_to_ibm860_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm860 = /* defined in cet.h */ +{ + cet_cs_name_ibm860, /* name of character set */ + cet_cs_alias_ibm860, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm860, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm860, /* first non standard character */ + cet_ucs4_cnt_ibm860, /* number of values in table */ + + cet_ucs4_to_ibm860_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm860_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm860_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e3, 0x00e0, 0x00c1, 0x00e7, + 0x00ea, 0x00ca, 0x00e8, 0x00ce, 0x00d4, 0x00ec, 0x00c3, 0x00c2, + 0x00c9, 0x00c0, 0x00c8, 0x00f4, 0x00f5, 0x00f2, 0x00da, 0x00f9, + 0x00cc, 0x00d5, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00d3, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm861.h b/cet/ibm861.h new file mode 100644 index 000000000..cd8520f4e --- /dev/null +++ b/cet/ibm861.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM861" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm861_h +#define ibm861_h + +#define cet_cs_name_ibm861 "IBM861" + +const char *cet_cs_alias_ibm861[] = +{ + "IBM861", "861", "CP861", "cp-is", + NULL +}; + +#define cet_ucs4_ofs_ibm861 128 +#define cet_ucs4_cnt_ibm861 128 + +const int cet_ucs4_map_ibm861[cet_ucs4_cnt_ibm861] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00d0, 0x00f0, 0x00de, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00fe, 0x00fb, 0x00dd, + 0x00fd, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00c1, 0x00cd, 0x00d3, 0x00da, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm861_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm861_links[cet_ucs4_to_ibm861_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a3, 0x9c} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c1, 0xa4} /* capital letter a with acute */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cd, 0xa5} /* capital letter i with acute */, + {0x00d0, 0x8b} /* capital letter eth (icelandic) */, + {0x00d2, 0x9f} /* capital letter o with grave */, + {0x00d3, 0xa6} /* capital letter o with acute */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00da, 0xa7} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0x97} /* capital letter y with acute */, + {0x00de, 0x8d} /* capital letter thorn (icelandic) */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f0, 0x8c} /* small letter eth (icelandic) */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0x98} /* small letter y with acute */, + {0x00fe, 0x95} /* small letter thorn (icelandic) */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm861_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm861_extra[cet_ucs4_to_ibm861_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm861 = /* defined in cet.h */ +{ + cet_cs_name_ibm861, /* name of character set */ + cet_cs_alias_ibm861, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm861, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm861, /* first non standard character */ + cet_ucs4_cnt_ibm861, /* number of values in table */ + + cet_ucs4_to_ibm861_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm861_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm861_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00d0, 0x00f0, 0x00de, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00fe, 0x00fb, 0x00dd, + 0x00fd, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00c1, 0x00cd, 0x00d3, 0x00da, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm862.h b/cet/ibm862.h new file mode 100644 index 000000000..f7a559f65 --- /dev/null +++ b/cet/ibm862.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM862" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm862_h +#define ibm862_h + +#define cet_cs_name_ibm862 "IBM862" + +const char *cet_cs_alias_ibm862[] = +{ + "IBM862", "862", "CP862", NULL +}; + +#define cet_ucs4_ofs_ibm862 128 +#define cet_ucs4_cnt_ibm862 128 + +const int cet_ucs4_map_ibm862[cet_ucs4_cnt_ibm862] = +{ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm862_ct 127 + +const cet_ucs4_link_t cet_ucs4_to_ibm862_links[cet_ucs4_to_ibm862_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d2, 0x9f} /* capital letter o with grave */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x03c6, 0xed} /* small letter phi */, + {0x05d0, 0x80} /* letter alef */, + {0x05d1, 0x81} /* letter bet */, + {0x05d2, 0x82} /* letter gimel */, + {0x05d3, 0x83} /* letter dalet */, + {0x05d4, 0x84} /* letter he */, + {0x05d5, 0x85} /* letter vav */, + {0x05d6, 0x86} /* letter zayin */, + {0x05d7, 0x87} /* letter het */, + {0x05d8, 0x88} /* letter tet */, + {0x05d9, 0x89} /* letter yod */, + {0x05da, 0x8a} /* letter final kaf */, + {0x05db, 0x8b} /* letter kaf */, + {0x05dc, 0x8c} /* letter lamed */, + {0x05dd, 0x8d} /* letter final mem */, + {0x05de, 0x8e} /* letter mem */, + {0x05df, 0x8f} /* letter final nun */, + {0x05e0, 0x90} /* letter nun */, + {0x05e1, 0x91} /* letter samekh */, + {0x05e2, 0x92} /* letter ayin */, + {0x05e3, 0x93} /* letter final pe */, + {0x05e4, 0x94} /* letter pe */, + {0x05e5, 0x95} /* letter final tsadi */, + {0x05e6, 0x96} /* letter tsadi */, + {0x05e7, 0x97} /* letter qof */, + {0x05e8, 0x98} /* letter resh */, + {0x05e9, 0x99} /* letter shin */, + {0x05ea, 0x9a} /* letter tav */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm862_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm862_extra[cet_ucs4_to_ibm862_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm862 = /* defined in cet.h */ +{ + cet_cs_name_ibm862, /* name of character set */ + cet_cs_alias_ibm862, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm862, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm862, /* first non standard character */ + cet_ucs4_cnt_ibm862, /* number of values in table */ + + cet_ucs4_to_ibm862_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm862_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm862_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d2, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, -1, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm863.h b/cet/ibm863.h new file mode 100644 index 000000000..97909f6db --- /dev/null +++ b/cet/ibm863.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM863" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm863_h +#define ibm863_h + +#define cet_cs_name_ibm863 "IBM863" + +const char *cet_cs_alias_ibm863[] = +{ + "IBM863", "863", "CP863", NULL +}; + +#define cet_ucs4_ofs_ibm863 128 +#define cet_ucs4_cnt_ibm863 128 + +const int cet_ucs4_map_ibm863[cet_ucs4_cnt_ibm863] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00c2, 0x00e0, 0x00b6, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c0, 0x00a7, + 0x00c9, 0x00c8, 0x00ca, 0x00f4, 0x00cb, 0x00cf, 0x00fb, 0x00f9, + 0x00a4, 0x00d4, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x00db, 0x0192, + 0x00a6, 0x00b4, 0x00f3, 0x00fa, 0x00a8, 0x00b8, 0x00b3, 0x00af, + 0x00ce, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00be, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm863_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm863_links[cet_ucs4_to_ibm863_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a2, 0x9b} /* sign */, + {0x00a3, 0x9c} /* sign */, + {0x00a4, 0x98} /* sign */, + {0x00a6, 0xa0} /* bar */, + {0x00a7, 0x8f} /* sign */, + {0x00a8, 0xa4} /* diaeresis */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00af, 0xa7} /* macron */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b3, 0xa6} /* three */, + {0x00b4, 0xa1} /* accent */, + {0x00b5, 0xe6} /* sign */, + {0x00b6, 0x86} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00b8, 0xa5} /* cedilla */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00be, 0xad} /* fraction three quarters */, + {0x00c0, 0x8e} /* capital letter a with grave */, + {0x00c2, 0x84} /* capital letter a with circumflex */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c8, 0x91} /* capital letter e with grave */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00ca, 0x92} /* capital letter e with circumflex */, + {0x00cb, 0x94} /* capital letter e with diaeresis */, + {0x00ce, 0xa8} /* capital letter i with circumflex */, + {0x00cf, 0x95} /* capital letter i with diaeresis */, + {0x00d4, 0x99} /* capital letter o with circumflex */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00db, 0x9e} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f7, 0xf6} /* sign */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm863_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm863_extra[cet_ucs4_to_ibm863_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm863 = /* defined in cet.h */ +{ + cet_cs_name_ibm863, /* name of character set */ + cet_cs_alias_ibm863, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm863, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm863, /* first non standard character */ + cet_ucs4_cnt_ibm863, /* number of values in table */ + + cet_ucs4_to_ibm863_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm863_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm863_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00c2, 0x00e0, 0x00b6, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c0, 0x00a7, + 0x00c9, 0x00c8, 0x00ca, 0x00f4, 0x00cb, 0x00cf, 0x00fb, 0x00f9, + 0x00a4, 0x00d4, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x00db, 0x0192, + 0x00a6, 0x00b4, 0x00f3, 0x00fa, 0x00a8, 0x00b8, 0x00b3, 0x00af, + 0x00ce, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00be, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm864.h b/cet/ibm864.h new file mode 100644 index 000000000..5dfac836f --- /dev/null +++ b/cet/ibm864.h @@ -0,0 +1,249 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM864" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm864_h +#define ibm864_h + +#define cet_cs_name_ibm864 "IBM864" + +const char *cet_cs_alias_ibm864[] = +{ + "IBM864", "864", "CP864", NULL +}; + +#define cet_ucs4_ofs_ibm864 128 +#define cet_ucs4_cnt_ibm864 128 + +const int cet_ucs4_map_ibm864[cet_ucs4_cnt_ibm864] = +{ + 0x00b0, 0x00b7, 0x2218, 0x221a, 0x2592, 0x2500, 0x2502, 0x253c, + 0x2524, 0x252c, 0x251c, 0x2534, 0x2510, 0x250c, 0x2514, 0x2518, + 0x00df, 0x221e, 0x00f8, 0x00b1, 0x00bd, 0x00bc, 0x2248, 0x00ab, + 0x00bb, 0xfef7, 0xfef8, -1, -1, 0xfefb, 0xfefc, 0xe016, + -1, 0x00ad, 0xfe82, 0x00a3, 0x00a4, 0xfe84, -1, -1, + 0xfe8e, 0x0628, 0x062a, 0x062b, 0x060c, 0x062c, 0x062d, 0x062e, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x06a4, 0x061b, 0x0633, 0x0634, 0x0635, 0x061f, + 0x00a2, 0x0621, 0x0622, 0x0623, 0x0624, 0xfeca, 0x0626, 0x0627, + 0xfe91, 0x0629, 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0xfea7, 0x062f, + 0x0630, 0x0631, 0x0632, 0xfeb3, 0xfeb7, 0xfebb, 0xfebf, 0x0637, + 0x0638, 0xfecb, 0xfecf, 0x00a6, 0x00ac, 0x00f7, 0x00d7, 0x0639, + 0x0640, 0xfed2, 0xfed6, 0xfedb, 0xfede, 0xfee3, 0xfee6, 0xfeeb, + 0x0648, 0x0649, 0xfef3, 0x0636, 0xfee2, 0xfece, 0x063a, 0x0645, + 0xfe7d, 0x0651, 0x0646, 0x0647, 0xfeec, 0xfef0, 0xfef2, 0x0641, + 0x0642, 0xfef5, 0xfef6, 0x0644, 0x0643, 0x064a, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm864_ct 121 + +const cet_ucs4_link_t cet_ucs4_to_ibm864_links[cet_ucs4_to_ibm864_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a2, 0xc0} /* sign */, + {0x00a6, 0xdb} /* bar */, + {0x00ab, 0x97} /* double angle quotation mark */, + {0x00ac, 0xdc} /* sign */, + {0x00ad, 0xa1} /* hyphen */, + {0x00b0, 0x80} /* sign */, + {0x00b1, 0x93} /* sign */, + {0x00b7, 0x81} /* dot */, + {0x00bb, 0x98} /* double angle quotation mark */, + {0x00bc, 0x95} /* fraction one quarter */, + {0x00bd, 0x94} /* fraction one half */, + {0x00d7, 0xde} /* sign */, + {0x00df, 0x90} /* small letter sharp s (german) */, + {0x00f7, 0xdd} /* sign */, + {0x00f8, 0x92} /* small letter o with stroke */, + {0x060c, 0xac} /* comma */, + {0x061b, 0xbb} /* semicolon */, + {0x061f, 0xbf} /* question mark */, + {0x0621, 0xc1} /* letter hamza */, + {0x0622, 0xc2} /* letter alef with madda above */, + {0x0623, 0xc3} /* letter alef with hamza above */, + {0x0624, 0xc4} /* letter waw with hamza above */, + {0x0626, 0xc6} /* letter yeh with hamza above */, + {0x0627, 0xc7} /* letter alef */, + {0x0628, 0xa9} /* letter beh */, + {0x0629, 0xc9} /* letter teh marbuta */, + {0x062a, 0xaa} /* letter teh */, + {0x062b, 0xab} /* letter theh */, + {0x062c, 0xad} /* letter jeem */, + {0x062d, 0xae} /* letter hah */, + {0x062e, 0xaf} /* letter khah */, + {0x062f, 0xcf} /* letter dal */, + {0x0630, 0xd0} /* letter thal */, + {0x0631, 0xd1} /* letter reh */, + {0x0632, 0xd2} /* letter zain */, + {0x0633, 0xbc} /* letter seen */, + {0x0634, 0xbd} /* letter sheen */, + {0x0635, 0xbe} /* letter sad */, + {0x0636, 0xeb} /* letter dad */, + {0x0637, 0xd7} /* letter tah */, + {0x0638, 0xd8} /* letter zah */, + {0x0639, 0xdf} /* letter ain */, + {0x063a, 0xee} /* letter ghain */, + {0x0640, 0xe0} /* tatweel */, + {0x0641, 0xf7} /* letter feh */, + {0x0642, 0xf8} /* letter qaf */, + {0x0643, 0xfc} /* letter kaf */, + {0x0644, 0xfb} /* letter lam */, + {0x0645, 0xef} /* letter meem */, + {0x0646, 0xf2} /* letter noon */, + {0x0647, 0xf3} /* letter heh */, + {0x0648, 0xe8} /* letter waw */, + {0x0649, 0xe9} /* letter alef maksura */, + {0x064a, 0xfd} /* letter yeh */, + {0x0651, 0xf1} /* shadda */, + {0x0660, 0xb0} /* arabic-indic digit zero */, + {0x0661, 0xb1} /* arabic-indic digit one */, + {0x0662, 0xb2} /* arabic-indic digit two */, + {0x0663, 0xb3} /* arabic-indic digit three */, + {0x0664, 0xb4} /* arabic-indic digit four */, + {0x0665, 0xb5} /* arabic-indic digit five */, + {0x0666, 0xb6} /* arabic-indic digit six */, + {0x0667, 0xb7} /* arabic-indic digit seven */, + {0x0668, 0xb8} /* arabic-indic digit eight */, + {0x0669, 0xb9} /* arabic-indic digit nine */, + {0x06a4, 0xba} /* letter veh */, + {0x2218, 0x82} /* operator */, + {0x221a, 0x83} /* root */, + {0x221e, 0x91} /* infinity */, + {0x2248, 0x96} /* equal to */, + {0x2500, 0x85} /* drawings light horizontal */, + {0x2502, 0x86} /* drawings light vertical */, + {0x250c, 0x8d} /* drawings light down and right */, + {0x2510, 0x8c} /* drawings light down and left */, + {0x2514, 0x8e} /* drawings light up and right */, + {0x2518, 0x8f} /* drawings light up and left */, + {0x251c, 0x8a} /* drawings light vertical and right */, + {0x2524, 0x88} /* drawings light vertical and left */, + {0x252c, 0x89} /* drawings light down and horizontal */, + {0x2534, 0x8b} /* drawings light up and horizontal */, + {0x253c, 0x87} /* drawings light vertical and horizontal */, + {0x2592, 0x84} /* shade */, + {0x25a0, 0xfe} /* square */, + {0xe016, 0x9f} /* letter alef final form compatibility (ibm868 144) */, + {0xfe7d, 0xf0} /* shadda medial form */, + {0xfe82, 0xa2} /* letter alef with madda above final form */, + {0xfe84, 0xa5} /* letter alef with hamza above final form */, + {0xfe8e, 0xa8} /* letter alef final form */, + {0xfe91, 0xc8} /* letter beh initial form */, + {0xfe97, 0xca} /* letter teh initial form */, + {0xfe9b, 0xcb} /* letter theh initial form */, + {0xfe9f, 0xcc} /* letter jeem initial form */, + {0xfea3, 0xcd} /* letter hah initial form */, + {0xfea7, 0xce} /* letter khah initial form */, + {0xfeb3, 0xd3} /* letter seen initial form */, + {0xfeb7, 0xd4} /* letter sheen initial form */, + {0xfebb, 0xd5} /* letter sad initial form */, + {0xfebf, 0xd6} /* letter dad initial form */, + {0xfeca, 0xc5} /* letter ain final form */, + {0xfecb, 0xd9} /* letter ain initial form */, + {0xfece, 0xed} /* letter ghain final form */, + {0xfecf, 0xda} /* letter ghain initial form */, + {0xfed2, 0xe1} /* letter feh final form */, + {0xfed6, 0xe2} /* letter qaf final form */, + {0xfedb, 0xe3} /* letter kaf initial form */, + {0xfede, 0xe4} /* letter lam final form */, + {0xfee2, 0xec} /* letter meem final form */, + {0xfee3, 0xe5} /* letter meem initial form */, + {0xfee6, 0xe6} /* letter noon final form */, + {0xfeeb, 0xe7} /* letter heh initial form */, + {0xfeec, 0xf4} /* letter heh medial form */, + {0xfef0, 0xf5} /* letter alef maksura final form */, + {0xfef2, 0xf6} /* letter yeh final form */, + {0xfef3, 0xea} /* letter yeh initial form */, + {0xfef5, 0xf9} /* ligature lam with alef with madda above */, + {0xfef6, 0xfa} /* ligature lam with alef with madda above */, + {0xfef7, 0x99} /* ligature lam with alef with hamza above */, + {0xfef8, 0x9a} /* ligature lam with alef with hamza above */, + {0xfefb, 0x9d} /* ligature lam with alef isolated form */, + {0xfefc, 0x9e} /* ligature lam with alef final form */ +}; + +/* +#define cet_ucs4_to_ibm864_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm864_extra[cet_ucs4_to_ibm864_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm864 = /* defined in cet.h */ +{ + cet_cs_name_ibm864, /* name of character set */ + cet_cs_alias_ibm864, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm864, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm864, /* first non standard character */ + cet_ucs4_cnt_ibm864, /* number of values in table */ + + cet_ucs4_to_ibm864_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm864_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm864_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00b0, 0x00b7, 0x2218, 0x221a, 0x2592, 0x2500, 0x2502, 0x253c, + 0x2524, 0x252c, 0x251c, 0x2534, 0x2510, 0x250c, 0x2514, 0x2518, + 0x00df, 0x221e, 0x00f8, 0x00b1, 0x00bd, 0x00bc, 0x2248, 0x00ab, + 0x00bb, 0xfef7, 0xfef8, -1, -1, 0xfefb, 0xfefc, 0xe016, + -1, 0x00ad, 0xfe82, 0x00a3, 0x00a4, 0xfe84, -1, -1, + 0xfe8e, 0x0628, 0x062a, 0x062b, 0x060c, 0x062c, 0x062d, 0x062e, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x06a4, 0x061b, 0x0633, 0x0634, 0x0635, 0x061f, + 0x00a2, 0x0621, 0x0622, 0x0623, 0x0624, 0xfeca, 0x0626, 0x0627, + 0xfe91, 0x0629, 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0xfea7, 0x062f, + 0x0630, 0x0631, 0x0632, 0xfeb3, 0xfeb7, 0xfebb, 0xfebf, 0x0637, + 0x0638, 0xfecb, 0xfecf, 0x00a6, 0x00ac, 0x00f7, 0x00d7, 0x0639, + 0x0640, 0xfed2, 0xfed6, 0xfedb, 0xfede, 0xfee3, 0xfee6, 0xfeeb, + 0x0648, 0x0649, 0xfef3, 0x0636, 0xfee2, 0xfece, 0x063a, 0x0645, + 0xfe7d, 0x0651, 0x0646, 0x0647, 0xfeec, 0xfef0, 0xfef2, 0x0641, + 0x0642, 0xfef5, 0xfef6, 0x0644, 0x0643, 0x064a, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm865.h b/cet/ibm865.h new file mode 100644 index 000000000..2cde68dd8 --- /dev/null +++ b/cet/ibm865.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM865" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm865_h +#define ibm865_h + +#define cet_cs_name_ibm865 "IBM865" + +const char *cet_cs_alias_ibm865[] = +{ + "IBM865", "865", "CP865", NULL +}; + +#define cet_ucs4_ofs_ibm865 128 +#define cet_ucs4_cnt_ibm865 128 + +const int cet_ucs4_map_ibm865[cet_ucs4_cnt_ibm865] = +{ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm865_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_ibm865_links[cet_ucs4_to_ibm865_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a1, 0xad} /* exclamation mark */, + {0x00a3, 0x9c} /* sign */, + {0x00aa, 0xa6} /* ordinal indicator */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0xaa} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b5, 0xe6} /* sign */, + {0x00b7, 0xf9} /* dot */, + {0x00ba, 0xa7} /* ordinal indicator */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00bd, 0xab} /* fraction one half */, + {0x00bf, 0xa8} /* question mark */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c5, 0x8f} /* capital letter a with ring above */, + {0x00c6, 0x92} /* capital letter ae */, + {0x00c7, 0x80} /* capital letter c with cedilla */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00d1, 0xa5} /* capital letter n with tilde */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00d8, 0x9d} /* capital letter o with stroke */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00df, 0xe1} /* small letter sharp s (german) */, + {0x00e0, 0x85} /* small letter a with grave */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e2, 0x83} /* small letter a with circumflex */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e5, 0x86} /* small letter a with ring above */, + {0x00e6, 0x91} /* small letter ae */, + {0x00e7, 0x87} /* small letter c with cedilla */, + {0x00e8, 0x8a} /* small letter e with grave */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ea, 0x88} /* small letter e with circumflex */, + {0x00eb, 0x89} /* small letter e with diaeresis */, + {0x00ec, 0x8d} /* small letter i with grave */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00ee, 0x8c} /* small letter i with circumflex */, + {0x00ef, 0x8b} /* small letter i with diaeresis */, + {0x00f1, 0xa4} /* small letter n with tilde */, + {0x00f2, 0x95} /* small letter o with grave */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00f8, 0x9b} /* small letter o with stroke */, + {0x00f9, 0x97} /* small letter u with grave */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fb, 0x96} /* small letter u with circumflex */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00ff, 0x98} /* small letter y with diaeresis */, + {0x0192, 0x9f} /* minuscule latine f hameçon */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x2022, 0xfa} /* puce */, + {0x207f, 0xfc} /* latin small letter n */, + {0x20a7, 0x9e} /* sign */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2310, 0xa9} /* not sign */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm865_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm865_extra[cet_ucs4_to_ibm865_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm865 = /* defined in cet.h */ +{ + cet_cs_name_ibm865, /* name of character set */ + cet_cs_alias_ibm865, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm865, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm865, /* first non standard character */ + cet_ucs4_cnt_ibm865, /* number of values in table */ + + cet_ucs4_to_ibm865_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm865_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm865_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2022, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm868.h b/cet/ibm868.h new file mode 100644 index 000000000..1c278ef62 --- /dev/null +++ b/cet/ibm868.h @@ -0,0 +1,232 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM868" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm868_h +#define ibm868_h + +#define cet_cs_name_ibm868 "IBM868" + +const char *cet_cs_alias_ibm868[] = +{ + "IBM868", "868", "CP868", "cp-ar", + NULL +}; + +#define cet_ucs4_ofs_ibm868 128 +#define cet_ucs4_cnt_ibm868 128 + +const int cet_ucs4_map_ibm868[cet_ucs4_cnt_ibm868] = +{ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x060c, 0x061b, 0x061f, 0x0622, 0x0627, 0xfe8e, + 0xe016, 0x0628, 0xfe91, 0x067e, -1, 0x0629, 0x062a, 0xfe97, + -1, -1, 0x062b, 0xfe9b, 0x062c, 0xfe9f, -1, -1, + 0x062d, 0xfea3, 0x062e, 0xfea7, 0x062f, -1, 0x0630, 0x0631, + -1, 0x0632, -1, 0x0633, 0xfeb3, 0x0634, 0x00ab, 0x00bb, + 0xfeb7, 0x0635, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xfebb, + 0x0636, 0xfebf, 0x0637, 0x2563, 0x2551, 0x2557, 0x255d, 0x0638, + 0x0639, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, + 0xfeca, 0xfecb, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, + 0x256c, 0xfecc, 0x063a, 0xfece, 0xfecf, 0xfed0, 0x0641, 0xfed3, + 0x0642, 0xfed7, 0xfeda, 0x2518, 0x250c, 0x2588, 0x2580, 0xfedb, + -1, 0x2584, -1, 0x0644, 0xfede, 0xfee0, 0x0645, 0xfee3, + -1, 0x0646, 0xfee7, -1, 0x0648, -1, -1, -1, + -1, 0x0621, 0x00ad, -1, -1, -1, -1, -1, + -1, -1, -1, 0x0651, 0xfe7d, -1, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm868_ct 103 + +const cet_ucs4_link_t cet_ucs4_to_ibm868_links[cet_ucs4_to_ibm868_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ad, 0xf2} /* hyphen */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x060c, 0x8a} /* comma */, + {0x061b, 0x8b} /* semicolon */, + {0x061f, 0x8c} /* question mark */, + {0x0621, 0xf1} /* letter hamza */, + {0x0622, 0x8d} /* letter alef with madda above */, + {0x0627, 0x8e} /* letter alef */, + {0x0628, 0x91} /* letter beh */, + {0x0629, 0x95} /* letter teh marbuta */, + {0x062a, 0x96} /* letter teh */, + {0x062b, 0x9a} /* letter theh */, + {0x062c, 0x9c} /* letter jeem */, + {0x062d, 0xa0} /* letter hah */, + {0x062e, 0xa2} /* letter khah */, + {0x062f, 0xa4} /* letter dal */, + {0x0630, 0xa6} /* letter thal */, + {0x0631, 0xa7} /* letter reh */, + {0x0632, 0xa9} /* letter zain */, + {0x0633, 0xab} /* letter seen */, + {0x0634, 0xad} /* letter sheen */, + {0x0635, 0xb1} /* letter sad */, + {0x0636, 0xb8} /* letter dad */, + {0x0637, 0xba} /* letter tah */, + {0x0638, 0xbf} /* letter zah */, + {0x0639, 0xc0} /* letter ain */, + {0x063a, 0xd2} /* letter ghain */, + {0x0641, 0xd6} /* letter feh */, + {0x0642, 0xd8} /* letter qaf */, + {0x0644, 0xe3} /* letter lam */, + {0x0645, 0xe6} /* letter meem */, + {0x0646, 0xe9} /* letter noon */, + {0x0648, 0xec} /* letter waw */, + {0x0651, 0xfb} /* shadda */, + {0x0660, 0x80} /* arabic-indic digit zero */, + {0x0661, 0x81} /* arabic-indic digit one */, + {0x0662, 0x82} /* arabic-indic digit two */, + {0x0663, 0x83} /* arabic-indic digit three */, + {0x0664, 0x84} /* arabic-indic digit four */, + {0x0665, 0x85} /* arabic-indic digit five */, + {0x0666, 0x86} /* arabic-indic digit six */, + {0x0667, 0x87} /* arabic-indic digit seven */, + {0x0668, 0x88} /* arabic-indic digit eight */, + {0x0669, 0x89} /* arabic-indic digit nine */, + {0x067e, 0x93} /* letter peh */, + {0x2500, 0xc6} /* drawings light horizontal */, + {0x2502, 0xb5} /* drawings light vertical */, + {0x250c, 0xdc} /* drawings light down and right */, + {0x2510, 0xc1} /* drawings light down and left */, + {0x2514, 0xc2} /* drawings light up and right */, + {0x2518, 0xdb} /* drawings light up and left */, + {0x251c, 0xc5} /* drawings light vertical and right */, + {0x2524, 0xb6} /* drawings light vertical and left */, + {0x252c, 0xc4} /* drawings light down and horizontal */, + {0x2534, 0xc3} /* drawings light up and horizontal */, + {0x253c, 0xc7} /* drawings light vertical and horizontal */, + {0x2550, 0xcf} /* drawings heavy horizontal */, + {0x2551, 0xbc} /* drawings heavy vertical */, + {0x2554, 0xcb} /* drawings heavy down and right */, + {0x2557, 0xbd} /* drawings heavy down and left */, + {0x255a, 0xca} /* drawings heavy up and right */, + {0x255d, 0xbe} /* drawings heavy up and left */, + {0x2560, 0xce} /* drawings heavy vertical and right */, + {0x2563, 0xbb} /* drawings heavy vertical and left */, + {0x2566, 0xcd} /* drawings heavy down and horizontal */, + {0x2569, 0xcc} /* drawings heavy up and horizontal */, + {0x256c, 0xd0} /* drawings heavy vertical and horizontal */, + {0x2580, 0xde} /* half block */, + {0x2584, 0xe1} /* half block */, + {0x2588, 0xdd} /* block */, + {0x2591, 0xb2} /* shade */, + {0x2592, 0xb3} /* shade */, + {0x2593, 0xb4} /* shade */, + {0x25a0, 0xfe} /* square */, + {0xe016, 0x90} /* letter alef final form compatibility (ibm868 144) */, + {0xfe7d, 0xfc} /* shadda medial form */, + {0xfe8e, 0x8f} /* letter alef final form */, + {0xfe91, 0x92} /* letter beh initial form */, + {0xfe97, 0x97} /* letter teh initial form */, + {0xfe9b, 0x9b} /* letter theh initial form */, + {0xfe9f, 0x9d} /* letter jeem initial form */, + {0xfea3, 0xa1} /* letter hah initial form */, + {0xfea7, 0xa3} /* letter khah initial form */, + {0xfeb3, 0xac} /* letter seen initial form */, + {0xfeb7, 0xb0} /* letter sheen initial form */, + {0xfebb, 0xb7} /* letter sad initial form */, + {0xfebf, 0xb9} /* letter dad initial form */, + {0xfeca, 0xc8} /* letter ain final form */, + {0xfecb, 0xc9} /* letter ain initial form */, + {0xfecc, 0xd1} /* letter ain medial form */, + {0xfece, 0xd3} /* letter ghain final form */, + {0xfecf, 0xd4} /* letter ghain initial form */, + {0xfed0, 0xd5} /* letter ghain medial form */, + {0xfed3, 0xd7} /* letter feh initial form */, + {0xfed7, 0xd9} /* letter qaf initial form */, + {0xfeda, 0xda} /* letter kaf final form */, + {0xfedb, 0xdf} /* letter kaf initial form */, + {0xfede, 0xe4} /* letter lam final form */, + {0xfee0, 0xe5} /* letter lam medial form */, + {0xfee3, 0xe7} /* letter meem initial form */, + {0xfee7, 0xea} /* letter noon initial form */ +}; + +/* +#define cet_ucs4_to_ibm868_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm868_extra[cet_ucs4_to_ibm868_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm868 = /* defined in cet.h */ +{ + cet_cs_name_ibm868, /* name of character set */ + cet_cs_alias_ibm868, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm868, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm868, /* first non standard character */ + cet_ucs4_cnt_ibm868, /* number of values in table */ + + cet_ucs4_to_ibm868_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm868_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm868_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0x060c, 0x061b, 0x061f, 0x0622, 0x0627, 0xfe8e, + 0xe016, 0x0628, 0xfe91, 0x067e, -1, 0x0629, 0x062a, 0xfe97, + -1, -1, 0x062b, 0xfe9b, 0x062c, 0xfe9f, -1, -1, + 0x062d, 0xfea3, 0x062e, 0xfea7, 0x062f, -1, 0x0630, 0x0631, + -1, 0x0632, -1, 0x0633, 0xfeb3, 0x0634, 0x00ab, 0x00bb, + 0xfeb7, 0x0635, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xfebb, + 0x0636, 0xfebf, 0x0637, 0x2563, 0x2551, 0x2557, 0x255d, 0x0638, + 0x0639, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, + 0xfeca, 0xfecb, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, + 0x256c, 0xfecc, 0x063a, 0xfece, 0xfecf, 0xfed0, 0x0641, 0xfed3, + 0x0642, 0xfed7, 0xfeda, 0x2518, 0x250c, 0x2588, 0x2580, 0xfedb, + -1, 0x2584, -1, 0x0644, 0xfede, 0xfee0, 0x0645, 0xfee3, + -1, 0x0646, 0xfee7, -1, 0x0648, -1, -1, -1, + -1, 0x0621, 0x00ad, -1, -1, -1, -1, -1, + -1, -1, -1, 0x0651, 0xfe7d, -1, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm869.h b/cet/ibm869.h new file mode 100644 index 000000000..57f2d9e0f --- /dev/null +++ b/cet/ibm869.h @@ -0,0 +1,248 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM869" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm869_h +#define ibm869_h + +#define cet_cs_name_ibm869 "IBM869" + +const char *cet_cs_alias_ibm869[] = +{ + "IBM869", "869", "CP869", "cp-gr", + NULL +}; + +#define cet_ucs4_ofs_ibm869 128 +#define cet_ucs4_cnt_ibm869 128 + +const int cet_ucs4_map_ibm869[cet_ucs4_cnt_ibm869] = +{ + -1, -1, -1, -1, -1, -1, 0x0386, -1, + 0x00b7, 0x00ac, 0x00a6, 0x201b, 0x2019, 0x0388, 0x2014, 0x0389, + 0x038a, 0x03aa, 0x038c, -1, -1, 0x038e, 0x03ab, 0x00a9, + 0x038f, 0x00b2, 0x00b3, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039c, + 0x039d, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x0385, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_ibm869_ct 119 + +const cet_ucs4_link_t cet_ucs4_to_ibm869_links[cet_ucs4_to_ibm869_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a3, 0x9c} /* sign */, + {0x00a6, 0x8a} /* bar */, + {0x00a7, 0xf5} /* sign */, + {0x00a8, 0xf9} /* diaeresis */, + {0x00a9, 0x97} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00ac, 0x89} /* sign */, + {0x00ad, 0xf0} /* hyphen */, + {0x00b0, 0xf8} /* sign */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0x99} /* two */, + {0x00b3, 0x9a} /* three */, + {0x00b4, 0xef} /* accent */, + {0x00b7, 0x88} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bd, 0xab} /* fraction one half */, + {0x0385, 0xf7} /* accent and diaeresis (tonos and dialytika) */, + {0x0386, 0x86} /* capital letter alpha with acute */, + {0x0388, 0x8d} /* capital letter epsilon with acute */, + {0x0389, 0x8f} /* capital letter eta with acute */, + {0x038a, 0x90} /* capital letter iota with acute */, + {0x038c, 0x92} /* capital letter omicron with acute */, + {0x038e, 0x95} /* capital letter upsilon with acute */, + {0x038f, 0x98} /* capital letter omega with acute */, + {0x0390, 0xa1} /* small letter iota with acute and diaeresis */, + {0x0391, 0xa4} /* capital letter alpha */, + {0x0392, 0xa5} /* capital letter beta */, + {0x0393, 0xa6} /* capital letter gamma */, + {0x0394, 0xa7} /* capital letter delta */, + {0x0395, 0xa8} /* capital letter epsilon */, + {0x0396, 0xa9} /* capital letter zeta */, + {0x0397, 0xaa} /* capital letter eta */, + {0x0398, 0xac} /* capital letter theta */, + {0x0399, 0xad} /* capital letter iota */, + {0x039a, 0xb5} /* capital letter kappa */, + {0x039b, 0xb6} /* capital letter lamda */, + {0x039c, 0xb7} /* capital letter mu */, + {0x039d, 0xb8} /* capital letter nu */, + {0x039e, 0xbd} /* capital letter xi */, + {0x039f, 0xbe} /* capital letter omicron */, + {0x03a0, 0xc6} /* capital letter pi */, + {0x03a1, 0xc7} /* capital letter rho */, + {0x03a3, 0xcf} /* capital letter sigma */, + {0x03a4, 0xd0} /* capital letter tau */, + {0x03a5, 0xd1} /* capital letter upsilon */, + {0x03a6, 0xd2} /* capital letter phi */, + {0x03a7, 0xd3} /* capital letter chi */, + {0x03a8, 0xd4} /* capital letter psi */, + {0x03a9, 0xd5} /* capital letter omega */, + {0x03aa, 0x91} /* capital letter iota with diaeresis */, + {0x03ab, 0x96} /* capital letter upsilon with diaeresis */, + {0x03ac, 0x9b} /* small letter alpha with acute */, + {0x03ad, 0x9d} /* small letter epsilon with acute */, + {0x03ae, 0x9e} /* small letter eta with acute */, + {0x03af, 0x9f} /* small letter iota with acute */, + {0x03b0, 0xfc} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xd6} /* small letter alpha */, + {0x03b2, 0xd7} /* small letter beta */, + {0x03b3, 0xd8} /* small letter gamma */, + {0x03b4, 0xdd} /* small letter delta */, + {0x03b5, 0xde} /* small letter epsilon */, + {0x03b6, 0xe0} /* small letter zeta */, + {0x03b7, 0xe1} /* small letter eta */, + {0x03b8, 0xe2} /* small letter theta */, + {0x03b9, 0xe3} /* small letter iota */, + {0x03ba, 0xe4} /* small letter kappa */, + {0x03bb, 0xe5} /* small letter lamda */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03bd, 0xe7} /* small letter nu */, + {0x03be, 0xe8} /* small letter xi */, + {0x03bf, 0xe9} /* small letter omicron */, + {0x03c0, 0xea} /* small letter pi */, + {0x03c1, 0xeb} /* small letter rho */, + {0x03c2, 0xed} /* small letter final sigma */, + {0x03c3, 0xec} /* small letter sigma */, + {0x03c4, 0xee} /* small letter tau */, + {0x03c5, 0xf2} /* small letter upsilon */, + {0x03c6, 0xf3} /* small letter phi */, + {0x03c7, 0xf4} /* small letter chi */, + {0x03c8, 0xf6} /* small letter psi */, + {0x03c9, 0xfa} /* small letter omega */, + {0x03ca, 0xa0} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xa2} /* small letter omicron with acute */, + {0x03cd, 0xa3} /* small letter upsilon with acute */, + {0x03ce, 0xfd} /* small letter omega with acute */, + {0x2014, 0x8e} /* dash */, + {0x2019, 0x8c} /* single quotation mark */, + {0x201b, 0x8b} /* high-reversed-9 quotation mark */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_ibm869_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm869_extra[cet_ucs4_to_ibm869_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm869 = /* defined in cet.h */ +{ + cet_cs_name_ibm869, /* name of character set */ + cet_cs_alias_ibm869, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm869, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm869, /* first non standard character */ + cet_ucs4_cnt_ibm869, /* number of values in table */ + + cet_ucs4_to_ibm869_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm869_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm869_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, 0x0386, -1, + 0x00b7, 0x00ac, 0x00a6, 0x201b, 0x2019, 0x0388, 0x2014, 0x0389, + 0x038a, 0x03aa, 0x038c, -1, -1, 0x038e, 0x03ab, 0x00a9, + 0x038f, 0x00b2, 0x00b3, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039c, + 0x039d, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x00b4, + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x0385, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/ibm871.h b/cet/ibm871.h new file mode 100644 index 000000000..1fddaca3b --- /dev/null +++ b/cet/ibm871.h @@ -0,0 +1,381 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM871" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm871_h +#define ibm871_h + +#define cet_cs_name_ibm871 "IBM871" + +const char *cet_cs_alias_ibm871[] = +{ + "IBM871", "871", "CP871", "ebcdic-cp-is", + NULL +}; + +#define cet_ucs4_ofs_ibm871 4 +#define cet_ucs4_cnt_ibm871 252 + +const int cet_ucs4_map_ibm871[cet_ucs4_cnt_ibm871] = +{ + 0x009c, 0x0009, 0x0086, 0x007f, 0x0097, 0x008d, 0x008e, 0x000b, + 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, + 0x009d, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008f, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x000a, 0x0017, 0x001b, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x0005, 0x0006, 0x0007, 0x0090, 0x0091, 0x0016, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009a, 0x009b, + 0x0014, 0x0015, 0x009e, 0x001a, 0x0020, 0x00a0, 0x00e2, 0x00e4, + 0x00e0, 0x00e1, 0x00e3, 0x00e5, 0x00e7, 0x00f1, 0x00fe, 0x002e, + 0x003c, 0x0028, 0x002b, 0x0021, 0x0026, 0x00e9, 0x00ea, 0x00eb, + 0x00e8, 0x00ed, 0x00ee, 0x00ef, 0x00ec, 0x00df, 0x00c6, 0x0024, + 0x002a, 0x0029, 0x003b, 0x00d6, 0x002d, 0x002f, 0x00c2, 0x00c4, + 0x00c0, 0x00c1, 0x00c3, 0x00c5, 0x00c7, 0x00d1, 0x00a6, 0x002c, + 0x0025, 0x005f, 0x003e, 0x003f, 0x00f8, 0x00c9, 0x00ca, 0x00cb, + 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00f0, 0x003a, 0x0023, + 0x00d0, 0x0027, 0x003d, 0x0022, 0x00d8, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00ab, 0x00bb, + 0x0060, 0x00fd, 0x007b, 0x00b1, 0x00b0, 0x006a, 0x006b, 0x006c, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x00aa, 0x00ba, + 0x007d, 0x00b8, 0x005d, 0x00a4, 0x00b5, 0x00f6, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00a1, 0x00bf, + 0x0040, 0x00dd, 0x005b, 0x00ae, 0x00a2, 0x00a3, 0x00a5, 0x00b7, + 0x00a9, 0x00a7, 0x00b6, 0x00bc, 0x00bd, 0x00be, 0x00ac, 0x007c, + 0x00af, 0x00a8, 0x005c, 0x00d7, 0x00de, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00ad, 0x00f4, + 0x007e, 0x00f2, 0x00f3, 0x00f5, 0x00e6, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x00b9, 0x00fb, + 0x00fc, 0x00f9, 0x00fa, 0x00ff, 0x00b4, 0x00f7, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00b2, 0x00d4, + 0x005e, 0x00d2, 0x00d3, 0x00d5, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00b3, 0x00db, + 0x00dc, 0x00d9, 0x00da, 0x009f +}; + +#define cet_ucs4_to_ibm871_ct 236 + +const cet_ucs4_link_t cet_ucs4_to_ibm871_links[cet_ucs4_to_ibm871_ct] = +{ + {0x0004, 0x37} /* of transmission (eot) */, + {0x0005, 0x2d} /* (enq) */, + {0x0006, 0x2e} /* (ack) */, + {0x0007, 0x2f} /* (bel) */, + {0x0008, 0x16} /* (bs) */, + {0x0009, 0x05} /* tabulation (ht) */, + {0x000a, 0x25} /* feed (lf) */, + {0x0014, 0x3c} /* control four (dc4) */, + {0x0015, 0x3d} /* acknowledge (nak) */, + {0x0016, 0x32} /* idle (syn) */, + {0x0017, 0x26} /* of transmission block (etb) */, + {0x001a, 0x3f} /* (sub) */, + {0x001b, 0x27} /* (esc) */, + {0x0020, 0x40} /* space */, + {0x0021, 0x4f} /* mark */, + {0x0022, 0x7f} /* mark */, + {0x0023, 0x7b} /* sign */, + {0x0024, 0x5b} /* sign */, + {0x0025, 0x6c} /* sign */, + {0x0026, 0x50} /* ampersand */, + {0x0027, 0x7d} /* apostrophe */, + {0x0028, 0x4d} /* parenthesis */, + {0x0029, 0x5d} /* parenthesis */, + {0x002a, 0x5c} /* asterisk */, + {0x002b, 0x4e} /* sign */, + {0x002c, 0x6b} /* comma */, + {0x002d, 0x60} /* hyphen-minus */, + {0x002e, 0x4b} /* stop */, + {0x002f, 0x61} /* solidus */, + {0x0030, 0xf0} /* zero */, + {0x0031, 0xf1} /* one */, + {0x0032, 0xf2} /* two */, + {0x0033, 0xf3} /* three */, + {0x0034, 0xf4} /* four */, + {0x0035, 0xf5} /* five */, + {0x0036, 0xf6} /* six */, + {0x0037, 0xf7} /* seven */, + {0x0038, 0xf8} /* eight */, + {0x0039, 0xf9} /* nine */, + {0x003a, 0x7a} /* colon */, + {0x003b, 0x5e} /* semicolon */, + {0x003c, 0x4c} /* sign */, + {0x003d, 0x7e} /* sign */, + {0x003e, 0x6e} /* sign */, + {0x003f, 0x6f} /* mark */, + {0x0040, 0xac} /* at */, + {0x0041, 0xc1} /* capital letter a */, + {0x0042, 0xc2} /* capital letter b */, + {0x0043, 0xc3} /* capital letter c */, + {0x0044, 0xc4} /* capital letter d */, + {0x0045, 0xc5} /* capital letter e */, + {0x0046, 0xc6} /* capital letter f */, + {0x0047, 0xc7} /* capital letter g */, + {0x0048, 0xc8} /* capital letter h */, + {0x0049, 0xc9} /* capital letter i */, + {0x004a, 0xd1} /* capital letter j */, + {0x004b, 0xd2} /* capital letter k */, + {0x004c, 0xd3} /* capital letter l */, + {0x004d, 0xd4} /* capital letter m */, + {0x004e, 0xd5} /* capital letter n */, + {0x004f, 0xd6} /* capital letter o */, + {0x0050, 0xd7} /* capital letter p */, + {0x0051, 0xd8} /* capital letter q */, + {0x0052, 0xd9} /* capital letter r */, + {0x0053, 0xe2} /* capital letter s */, + {0x0054, 0xe3} /* capital letter t */, + {0x0055, 0xe4} /* capital letter u */, + {0x0056, 0xe5} /* capital letter v */, + {0x0057, 0xe6} /* capital letter w */, + {0x0058, 0xe7} /* capital letter x */, + {0x0059, 0xe8} /* capital letter y */, + {0x005a, 0xe9} /* capital letter z */, + {0x005b, 0xae} /* square bracket */, + {0x005c, 0xbe} /* solidus */, + {0x005d, 0x9e} /* square bracket */, + {0x005e, 0xec} /* accent */, + {0x005f, 0x6d} /* line */, + {0x0060, 0x8c} /* accent */, + {0x0061, 0x81} /* small letter a */, + {0x0062, 0x82} /* small letter b */, + {0x0063, 0x83} /* small letter c */, + {0x0064, 0x84} /* small letter d */, + {0x0065, 0x85} /* small letter e */, + {0x0066, 0x86} /* small letter f */, + {0x0067, 0x87} /* small letter g */, + {0x0068, 0x88} /* small letter h */, + {0x0069, 0x89} /* small letter i */, + {0x006a, 0x91} /* small letter j */, + {0x006b, 0x92} /* small letter k */, + {0x006c, 0x93} /* small letter l */, + {0x006d, 0x94} /* small letter m */, + {0x006e, 0x95} /* small letter n */, + {0x006f, 0x96} /* small letter o */, + {0x0070, 0x97} /* small letter p */, + {0x0071, 0x98} /* small letter q */, + {0x0072, 0x99} /* small letter r */, + {0x0073, 0xa2} /* small letter s */, + {0x0074, 0xa3} /* small letter t */, + {0x0075, 0xa4} /* small letter u */, + {0x0076, 0xa5} /* small letter v */, + {0x0077, 0xa6} /* small letter w */, + {0x0078, 0xa7} /* small letter x */, + {0x0079, 0xa8} /* small letter y */, + {0x007a, 0xa9} /* small letter z */, + {0x007b, 0x8e} /* curly bracket */, + {0x007c, 0xbb} /* line */, + {0x007d, 0x9c} /* curly bracket */, + {0x007e, 0xcc} /* tilde */, + {0x007f, 0x07} /* (del) */, + {0x0080, 0x20} /* character (pad) */, + {0x0081, 0x21} /* octet preset (hop) */, + {0x0082, 0x22} /* permitted here (bph) */, + {0x0083, 0x23} /* break here (nbh) */, + {0x0084, 0x24} /* (ind) */, + {0x0085, 0x15} /* line (nel) */, + {0x0086, 0x06} /* of selected area (ssa) */, + {0x0087, 0x17} /* of selected area (esa) */, + {0x0088, 0x28} /* tabulation set (hts) */, + {0x0089, 0x29} /* tabulation with justification (htj) */, + {0x008a, 0x2a} /* tabulation set (vts) */, + {0x008b, 0x2b} /* line forward (pld) */, + {0x008c, 0x2c} /* line backward (plu) */, + {0x008d, 0x09} /* line feed (ri) */, + {0x008e, 0x0a} /* two (ss2) */, + {0x008f, 0x1b} /* three (ss3) */, + {0x0090, 0x30} /* control string (dcs) */, + {0x0091, 0x31} /* use one (pu1) */, + {0x0092, 0x1a} /* use two (pu2) */, + {0x0093, 0x33} /* transmit state (sts) */, + {0x0094, 0x34} /* character (cch) */, + {0x0095, 0x35} /* waiting (mw) */, + {0x0096, 0x36} /* of guarded area (spa) */, + {0x0097, 0x08} /* of guarded area (epa) */, + {0x0098, 0x38} /* of string (sos) */, + {0x0099, 0x39} /* graphic character introducer (sgci) */, + {0x009a, 0x3a} /* character introducer (sci) */, + {0x009b, 0x3b} /* sequence introducer (csi) */, + {0x009c, 0x04} /* terminator (st) */, + {0x009d, 0x14} /* system command (osc) */, + {0x009e, 0x3e} /* message (pm) */, + {0x009f, 0xff} /* program command (apc) */, + {0x00a0, 0x41} /* space */, + {0x00a1, 0xaa} /* exclamation mark */, + {0x00a2, 0xb0} /* sign */, + {0x00a3, 0xb1} /* sign */, + {0x00a4, 0x9f} /* sign */, + {0x00a5, 0xb2} /* sign */, + {0x00a6, 0x6a} /* bar */, + {0x00a7, 0xb5} /* sign */, + {0x00a8, 0xbd} /* diaeresis */, + {0x00a9, 0xb4} /* sign */, + {0x00aa, 0x9a} /* ordinal indicator */, + {0x00ab, 0x8a} /* double angle quotation mark */, + {0x00ac, 0xba} /* sign */, + {0x00ad, 0xca} /* hyphen */, + {0x00ae, 0xaf} /* sign */, + {0x00af, 0xbc} /* macron */, + {0x00b0, 0x90} /* sign */, + {0x00b1, 0x8f} /* sign */, + {0x00b2, 0xea} /* two */, + {0x00b3, 0xfa} /* three */, + {0x00b4, 0xe0} /* accent */, + {0x00b5, 0xa0} /* sign */, + {0x00b7, 0xb3} /* dot */, + {0x00b8, 0x9d} /* cedilla */, + {0x00b9, 0xda} /* one */, + {0x00ba, 0x9b} /* ordinal indicator */, + {0x00bb, 0x8b} /* double angle quotation mark */, + {0x00bc, 0xb7} /* fraction one quarter */, + {0x00bd, 0xb8} /* fraction one half */, + {0x00be, 0xb9} /* fraction three quarters */, + {0x00bf, 0xab} /* question mark */, + {0x00c0, 0x64} /* capital letter a with grave */, + {0x00c1, 0x65} /* capital letter a with acute */, + {0x00c2, 0x62} /* capital letter a with circumflex */, + {0x00c3, 0x66} /* capital letter a with tilde */, + {0x00c4, 0x63} /* capital letter a with diaeresis */, + {0x00c5, 0x67} /* capital letter a with ring above */, + {0x00c6, 0x5a} /* capital letter ae */, + {0x00c7, 0x68} /* capital letter c with cedilla */, + {0x00c8, 0x74} /* capital letter e with grave */, + {0x00c9, 0x71} /* capital letter e with acute */, + {0x00ca, 0x72} /* capital letter e with circumflex */, + {0x00cb, 0x73} /* capital letter e with diaeresis */, + {0x00cc, 0x78} /* capital letter i with grave */, + {0x00cd, 0x75} /* capital letter i with acute */, + {0x00ce, 0x76} /* capital letter i with circumflex */, + {0x00cf, 0x77} /* capital letter i with diaeresis */, + {0x00d0, 0x7c} /* capital letter eth (icelandic) */, + {0x00d1, 0x69} /* capital letter n with tilde */, + {0x00d2, 0xed} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xeb} /* capital letter o with circumflex */, + {0x00d5, 0xef} /* capital letter o with tilde */, + {0x00d6, 0x5f} /* capital letter o with diaeresis */, + {0x00d7, 0xbf} /* sign */, + {0x00d8, 0x80} /* capital letter o with stroke */, + {0x00d9, 0xfd} /* capital letter u with grave */, + {0x00da, 0xfe} /* capital letter u with acute */, + {0x00db, 0xfb} /* capital letter u with circumflex */, + {0x00dc, 0xfc} /* capital letter u with diaeresis */, + {0x00dd, 0xad} /* capital letter y with acute */, + {0x00de, 0xc0} /* capital letter thorn (icelandic) */, + {0x00df, 0x59} /* small letter sharp s (german) */, + {0x00e0, 0x44} /* small letter a with grave */, + {0x00e1, 0x45} /* small letter a with acute */, + {0x00e2, 0x42} /* small letter a with circumflex */, + {0x00e3, 0x46} /* small letter a with tilde */, + {0x00e4, 0x43} /* small letter a with diaeresis */, + {0x00e5, 0x47} /* small letter a with ring above */, + {0x00e6, 0xd0} /* small letter ae */, + {0x00e7, 0x48} /* small letter c with cedilla */, + {0x00e8, 0x54} /* small letter e with grave */, + {0x00e9, 0x51} /* small letter e with acute */, + {0x00ea, 0x52} /* small letter e with circumflex */, + {0x00eb, 0x53} /* small letter e with diaeresis */, + {0x00ec, 0x58} /* small letter i with grave */, + {0x00ed, 0x55} /* small letter i with acute */, + {0x00ee, 0x56} /* small letter i with circumflex */, + {0x00ef, 0x57} /* small letter i with diaeresis */, + {0x00f0, 0x79} /* small letter eth (icelandic) */, + {0x00f1, 0x49} /* small letter n with tilde */, + {0x00f2, 0xcd} /* small letter o with grave */, + {0x00f3, 0xce} /* small letter o with acute */, + {0x00f4, 0xcb} /* small letter o with circumflex */, + {0x00f5, 0xcf} /* small letter o with tilde */, + {0x00f6, 0xa1} /* small letter o with diaeresis */, + {0x00f7, 0xe1} /* sign */, + {0x00f8, 0x70} /* small letter o with stroke */, + {0x00f9, 0xdd} /* small letter u with grave */, + {0x00fa, 0xde} /* small letter u with acute */, + {0x00fb, 0xdb} /* small letter u with circumflex */, + {0x00fc, 0xdc} /* small letter u with diaeresis */, + {0x00fd, 0x8d} /* small letter y with acute */, + {0x00fe, 0x4a} /* small letter thorn (icelandic) */, + {0x00ff, 0xdf} /* small letter y with diaeresis */ +}; + +/* +#define cet_ucs4_to_ibm871_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm871_extra[cet_ucs4_to_ibm871_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm871 = /* defined in cet.h */ +{ + cet_cs_name_ibm871, /* name of character set */ + cet_cs_alias_ibm871, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm871, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm871, /* first non standard character */ + cet_ucs4_cnt_ibm871, /* number of values in table */ + + cet_ucs4_to_ibm871_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm871_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm871_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x009c, 0x0009, 0x0086, 0x007f, + 0x0097, 0x008d, 0x008e, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x009d, 0x0085, 0x0008, 0x0087, + 0x0018, 0x0019, 0x0092, 0x008f, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000a, 0x0017, 0x001b, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x0005, 0x0006, 0x0007, + 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, + 0x0098, 0x0099, 0x009a, 0x009b, 0x0014, 0x0015, 0x009e, 0x001a, + 0x0020, 0x00a0, 0x00e2, 0x00e4, 0x00e0, 0x00e1, 0x00e3, 0x00e5, + 0x00e7, 0x00f1, 0x00fe, 0x002e, 0x003c, 0x0028, 0x002b, 0x0021, + 0x0026, 0x00e9, 0x00ea, 0x00eb, 0x00e8, 0x00ed, 0x00ee, 0x00ef, + 0x00ec, 0x00df, 0x00c6, 0x0024, 0x002a, 0x0029, 0x003b, 0x00d6, + 0x002d, 0x002f, 0x00c2, 0x00c4, 0x00c0, 0x00c1, 0x00c3, 0x00c5, + 0x00c7, 0x00d1, 0x00a6, 0x002c, 0x0025, 0x005f, 0x003e, 0x003f, + 0x00f8, 0x00c9, 0x00ca, 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, + 0x00cc, 0x00f0, 0x003a, 0x0023, 0x00d0, 0x0027, 0x003d, 0x0022, + 0x00d8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x00ab, 0x00bb, 0x0060, 0x00fd, 0x007b, 0x00b1, + 0x00b0, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x00aa, 0x00ba, 0x007d, 0x00b8, 0x005d, 0x00a4, + 0x00b5, 0x00f6, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x00a1, 0x00bf, 0x0040, 0x00dd, 0x005b, 0x00ae, + 0x00a2, 0x00a3, 0x00a5, 0x00b7, 0x00a9, 0x00a7, 0x00b6, 0x00bc, + 0x00bd, 0x00be, 0x00ac, 0x007c, 0x00af, 0x00a8, 0x005c, 0x00d7, + 0x00de, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x00ad, 0x00f4, 0x007e, 0x00f2, 0x00f3, 0x00f5, + 0x00e6, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x00b9, 0x00fb, 0x00fc, 0x00f9, 0x00fa, 0x00ff, + 0x00b4, 0x00f7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x00b2, 0x00d4, 0x005e, 0x00d2, 0x00d3, 0x00d5, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x00b3, 0x00db, 0x00dc, 0x00d9, 0x00da, 0x009f +}; +*/ + +#endif diff --git a/cet/ibm891.h b/cet/ibm891.h new file mode 100644 index 000000000..2d0f3a6ab --- /dev/null +++ b/cet/ibm891.h @@ -0,0 +1,108 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM891" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm891_h +#define ibm891_h + +#define cet_cs_name_ibm891 "IBM891" + +const char *cet_cs_alias_ibm891[] = +{ + "IBM891", "891", "CP891", NULL +}; + +#define cet_ucs4_ofs_ibm891 128 +#define cet_ucs4_cnt_ibm891 1 + +const int cet_ucs4_map_ibm891[cet_ucs4_cnt_ibm891]; + +#define cet_ucs4_to_ibm891_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ibm891_links[cet_ucs4_to_ibm891_ct]; + +/* +#define cet_ucs4_to_ibm891_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm891_extra[cet_ucs4_to_ibm891_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm891 = /* defined in cet.h */ +{ + cet_cs_name_ibm891, /* name of character set */ + cet_cs_alias_ibm891, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm891, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm891, /* first non standard character */ + cet_ucs4_cnt_ibm891, /* number of values in table */ + + cet_ucs4_to_ibm891_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm891_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm891_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ibm903.h b/cet/ibm903.h new file mode 100644 index 000000000..b9a4d6c19 --- /dev/null +++ b/cet/ibm903.h @@ -0,0 +1,108 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM903" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm903_h +#define ibm903_h + +#define cet_cs_name_ibm903 "IBM903" + +const char *cet_cs_alias_ibm903[] = +{ + "IBM903", "903", "CP903", NULL +}; + +#define cet_ucs4_ofs_ibm903 128 +#define cet_ucs4_cnt_ibm903 1 + +const int cet_ucs4_map_ibm903[cet_ucs4_cnt_ibm903]; + +#define cet_ucs4_to_ibm903_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ibm903_links[cet_ucs4_to_ibm903_ct]; + +/* +#define cet_ucs4_to_ibm903_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm903_extra[cet_ucs4_to_ibm903_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm903 = /* defined in cet.h */ +{ + cet_cs_name_ibm903, /* name of character set */ + cet_cs_alias_ibm903, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm903, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm903, /* first non standard character */ + cet_ucs4_cnt_ibm903, /* number of values in table */ + + cet_ucs4_to_ibm903_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm903_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm903_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ibm904.h b/cet/ibm904.h new file mode 100644 index 000000000..78f489c8b --- /dev/null +++ b/cet/ibm904.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IBM904" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ibm904_h +#define ibm904_h + +#define cet_cs_name_ibm904 "IBM904" + +const char *cet_cs_alias_ibm904[] = +{ + "IBM904", "904", "CP904", NULL +}; + +#define cet_ucs4_ofs_ibm904 128 +#define cet_ucs4_cnt_ibm904 127 + +const int cet_ucs4_map_ibm904[cet_ucs4_cnt_ibm904] = +{ + 0x00a2, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0x00ac, 0x00a6 +}; + +#define cet_ucs4_to_ibm904_ct 3 + +const cet_ucs4_link_t cet_ucs4_to_ibm904_links[cet_ucs4_to_ibm904_ct] = +{ + {0x00a2, 0x80} /* sign */, + {0x00a6, 0xfe} /* bar */, + {0x00ac, 0xfd} /* sign */ +}; + +/* +#define cet_ucs4_to_ibm904_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ibm904_extra[cet_ucs4_to_ibm904_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ibm904 = /* defined in cet.h */ +{ + cet_cs_name_ibm904, /* name of character set */ + cet_cs_alias_ibm904, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ibm904, /* char to UCS-4 value table */ + cet_ucs4_ofs_ibm904, /* first non standard character */ + cet_ucs4_cnt_ibm904, /* number of values in table */ + + cet_ucs4_to_ibm904_links, /* UCS-4 to char links */ + cet_ucs4_to_ibm904_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ibm904_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00a2, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0x00ac, 0x00a6, -1 +}; +*/ + +#endif diff --git a/cet/iec_p27_1.h b/cet/iec_p27_1.h new file mode 100644 index 000000000..44ba106bc --- /dev/null +++ b/cet/iec_p27_1.h @@ -0,0 +1,220 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IEC_P27-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iec_p27_1_h +#define iec_p27_1_h + +#define cet_cs_name_iec_p27_1 "IEC_P27-1" + +const char *cet_cs_alias_iec_p27_1[] = +{ + "IEC_P27-1", "iso-ir-143", NULL +}; + +#define cet_ucs4_ofs_iec_p27_1 160 +#define cet_ucs4_cnt_iec_p27_1 96 + +const int cet_ucs4_map_iec_p27_1[cet_ucs4_cnt_iec_p27_1] = +{ + 0x02c7, 0x2261, 0x2227, 0x2228, 0x2229, 0x222a, 0x2282, 0x2283, + 0x21d0, 0x21d2, 0x2234, 0x2235, 0x2208, 0x220b, 0x2286, 0x2287, + 0x222b, 0x222e, 0x221e, 0x2207, 0x2202, 0x223c, 0x2248, 0x2243, + 0x2245, 0x2264, 0x2260, 0x2265, 0x2194, 0x00ac, 0x2200, 0x2203, + 0x05d0, 0x25a1, 0x2225, 0x0393, 0x0394, 0x22a5, 0x2220, 0x221f, + 0x0398, 0x2329, 0x232a, 0x039b, 0x2032, 0x2033, 0x039e, 0x2213, + 0x03a0, 0x00b2, 0x03a3, 0x00d7, 0x00b3, 0x03a5, 0x03a6, 0x00b7, + 0x03a8, 0x03a9, 0x2205, 0x21c0, 0x221a, 0x0192, 0x221d, 0x00b1, + 0x00b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x2030, + 0x03c0, 0x03c1, 0x03c3, 0x00f7, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x2020, 0x2190, 0x2191, 0x2192, 0x2193, 0x203e +}; + +#define cet_ucs4_to_iec_p27_1_ct 96 + +const cet_ucs4_link_t cet_ucs4_to_iec_p27_1_links[cet_ucs4_to_iec_p27_1_ct] = +{ + {0x00ac, 0xbd} /* sign */, + {0x00b0, 0xe0} /* sign */, + {0x00b1, 0xdf} /* sign */, + {0x00b2, 0xd1} /* two */, + {0x00b3, 0xd4} /* three */, + {0x00b7, 0xd7} /* dot */, + {0x00d7, 0xd3} /* sign */, + {0x00f7, 0xf3} /* sign */, + {0x0192, 0xdd} /* minuscule latine f hameçon */, + {0x02c7, 0xa0} /* caron */, + {0x0393, 0xc3} /* capital letter gamma */, + {0x0394, 0xc4} /* capital letter delta */, + {0x0398, 0xc8} /* capital letter theta */, + {0x039b, 0xcb} /* capital letter lamda */, + {0x039e, 0xce} /* capital letter xi */, + {0x03a0, 0xd0} /* capital letter pi */, + {0x03a3, 0xd2} /* capital letter sigma */, + {0x03a5, 0xd5} /* capital letter upsilon */, + {0x03a6, 0xd6} /* capital letter phi */, + {0x03a8, 0xd8} /* capital letter psi */, + {0x03a9, 0xd9} /* capital letter omega */, + {0x03b1, 0xe1} /* small letter alpha */, + {0x03b2, 0xe2} /* small letter beta */, + {0x03b3, 0xe3} /* small letter gamma */, + {0x03b4, 0xe4} /* small letter delta */, + {0x03b5, 0xe5} /* small letter epsilon */, + {0x03b6, 0xe6} /* small letter zeta */, + {0x03b7, 0xe7} /* small letter eta */, + {0x03b8, 0xe8} /* small letter theta */, + {0x03b9, 0xe9} /* small letter iota */, + {0x03ba, 0xea} /* small letter kappa */, + {0x03bb, 0xeb} /* small letter lamda */, + {0x03bc, 0xec} /* small letter mu */, + {0x03bd, 0xed} /* small letter nu */, + {0x03be, 0xee} /* small letter xi */, + {0x03c0, 0xf0} /* small letter pi */, + {0x03c1, 0xf1} /* small letter rho */, + {0x03c3, 0xf2} /* small letter sigma */, + {0x03c4, 0xf4} /* small letter tau */, + {0x03c5, 0xf5} /* small letter upsilon */, + {0x03c6, 0xf6} /* small letter phi */, + {0x03c7, 0xf7} /* small letter chi */, + {0x03c8, 0xf8} /* small letter psi */, + {0x03c9, 0xf9} /* small letter omega */, + {0x05d0, 0xc0} /* letter alef */, + {0x2020, 0xfa} /* dagger */, + {0x2030, 0xef} /* mille sign */, + {0x2032, 0xcc} /* prime */, + {0x2033, 0xcd} /* prime */, + {0x203e, 0xff} /* overline */, + {0x2190, 0xfb} /* arrow */, + {0x2191, 0xfc} /* arrow */, + {0x2192, 0xfd} /* arrow */, + {0x2193, 0xfe} /* arrow */, + {0x2194, 0xbc} /* right arrow */, + {0x21c0, 0xdb} /* vector above (iso-10646-1dis 032/032/038/046) */, + {0x21d0, 0xa8} /* double arrow */, + {0x21d2, 0xa9} /* double arrow */, + {0x2200, 0xbe} /* all */, + {0x2202, 0xb4} /* differential */, + {0x2203, 0xbf} /* exists */, + {0x2205, 0xda} /* set */, + {0x2207, 0xb3} /* nabla */, + {0x2208, 0xac} /* of */, + {0x220b, 0xad} /* as member */, + {0x2213, 0xcf} /* sign */, + {0x221a, 0xdc} /* root */, + {0x221d, 0xde} /* to */, + {0x221e, 0xb2} /* infinity */, + {0x221f, 0xc7} /* angle */, + {0x2220, 0xc6} /* angle */, + {0x2225, 0xc2} /* to */, + {0x2227, 0xa2} /* and */, + {0x2228, 0xa3} /* or */, + {0x2229, 0xa4} /* intersection */, + {0x222a, 0xa5} /* union */, + {0x222b, 0xb0} /* integral */, + {0x222e, 0xb1} /* integral */, + {0x2234, 0xaa} /* therefore */, + {0x2235, 0xab} /* because */, + {0x223c, 0xb5} /* operator */, + {0x2243, 0xb7} /* equal to */, + {0x2245, 0xb8} /* equal to */, + {0x2248, 0xb6} /* equal to */, + {0x2260, 0xba} /* equal to */, + {0x2261, 0xa1} /* to */, + {0x2264, 0xb9} /* or equal to */, + {0x2265, 0xbb} /* or equal to */, + {0x2282, 0xa6} /* of */, + {0x2283, 0xa7} /* of */, + {0x2286, 0xae} /* of or equal to */, + {0x2287, 0xaf} /* of or equal to */, + {0x22a5, 0xc5} /* tack */, + {0x2329, 0xc9} /* angle bracket */, + {0x232a, 0xca} /* angle bracket */, + {0x25a1, 0xc1} /* square */ +}; + +/* +#define cet_ucs4_to_iec_p27_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iec_p27_1_extra[cet_ucs4_to_iec_p27_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iec_p27_1 = /* defined in cet.h */ +{ + cet_cs_name_iec_p27_1, /* name of character set */ + cet_cs_alias_iec_p27_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iec_p27_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_iec_p27_1, /* first non standard character */ + cet_ucs4_cnt_iec_p27_1, /* number of values in table */ + + cet_ucs4_to_iec_p27_1_links, /* UCS-4 to char links */ + cet_ucs4_to_iec_p27_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iec_p27_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x02c7, 0x2261, 0x2227, 0x2228, 0x2229, 0x222a, 0x2282, 0x2283, + 0x21d0, 0x21d2, 0x2234, 0x2235, 0x2208, 0x220b, 0x2286, 0x2287, + 0x222b, 0x222e, 0x221e, 0x2207, 0x2202, 0x223c, 0x2248, 0x2243, + 0x2245, 0x2264, 0x2260, 0x2265, 0x2194, 0x00ac, 0x2200, 0x2203, + 0x05d0, 0x25a1, 0x2225, 0x0393, 0x0394, 0x22a5, 0x2220, 0x221f, + 0x0398, 0x2329, 0x232a, 0x039b, 0x2032, 0x2033, 0x039e, 0x2213, + 0x03a0, 0x00b2, 0x03a3, 0x00d7, 0x00b3, 0x03a5, 0x03a6, 0x00b7, + 0x03a8, 0x03a9, 0x2205, 0x21c0, 0x221a, 0x0192, 0x221d, 0x00b1, + 0x00b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x2030, + 0x03c0, 0x03c1, 0x03c3, 0x00f7, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x2020, 0x2190, 0x2191, 0x2192, 0x2193, 0x203e +}; +*/ + +#endif diff --git a/cet/iso_10367_box.h b/cet/iso_10367_box.h new file mode 100644 index 000000000..c29333d0f --- /dev/null +++ b/cet/iso_10367_box.h @@ -0,0 +1,149 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_10367-box" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_10367_box_h +#define iso_10367_box_h + +#define cet_cs_name_iso_10367_box "ISO_10367-box" + +const char *cet_cs_alias_iso_10367_box[] = +{ + "ISO_10367-box", "iso-ir-155", NULL +}; + +#define cet_ucs4_ofs_iso_10367_box 160 +#define cet_ucs4_cnt_iso_10367_box 62 + +const int cet_ucs4_map_iso_10367_box[cet_ucs4_cnt_iso_10367_box] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x2551, 0x2550, 0x2554, 0x2557, 0x255a, 0x255d, 0x2560, 0x2563, + 0x2566, 0x2569, 0x256c, 0xe019, 0x2584, 0x2588, 0x25aa, -1, + 0x2502, 0x2500, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2591, 0x2592, 0x2593 +}; + +#define cet_ucs4_to_iso_10367_box_ct 29 + +const cet_ucs4_link_t cet_ucs4_to_iso_10367_box_links[cet_ucs4_to_iso_10367_box_ct] = +{ + {0x2500, 0xd1} /* drawings light horizontal */, + {0x2502, 0xd0} /* drawings light vertical */, + {0x250c, 0xd2} /* drawings light down and right */, + {0x2510, 0xd3} /* drawings light down and left */, + {0x2514, 0xd4} /* drawings light up and right */, + {0x2518, 0xd5} /* drawings light up and left */, + {0x251c, 0xd6} /* drawings light vertical and right */, + {0x2524, 0xd7} /* drawings light vertical and left */, + {0x252c, 0xd8} /* drawings light down and horizontal */, + {0x2534, 0xd9} /* drawings light up and horizontal */, + {0x253c, 0xda} /* drawings light vertical and horizontal */, + {0x2550, 0xc1} /* drawings heavy horizontal */, + {0x2551, 0xc0} /* drawings heavy vertical */, + {0x2554, 0xc2} /* drawings heavy down and right */, + {0x2557, 0xc3} /* drawings heavy down and left */, + {0x255a, 0xc4} /* drawings heavy up and right */, + {0x255d, 0xc5} /* drawings heavy up and left */, + {0x2560, 0xc6} /* drawings heavy vertical and right */, + {0x2563, 0xc7} /* drawings heavy vertical and left */, + {0x2566, 0xc8} /* drawings heavy down and horizontal */, + {0x2569, 0xc9} /* drawings heavy up and horizontal */, + {0x256c, 0xca} /* drawings heavy vertical and horizontal */, + {0x2584, 0xcc} /* half block */, + {0x2588, 0xcd} /* block */, + {0x2591, 0xdb} /* shade */, + {0x2592, 0xdc} /* shade */, + {0x2593, 0xdd} /* shade */, + {0x25aa, 0xce} /* small square */, + {0xe019, 0xcb} /* space b (iso-ir-8-1 096) */ +}; + +/* +#define cet_ucs4_to_iso_10367_box_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_10367_box_extra[cet_ucs4_to_iso_10367_box_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_10367_box = /* defined in cet.h */ +{ + cet_cs_name_iso_10367_box, /* name of character set */ + cet_cs_alias_iso_10367_box, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_10367_box, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_10367_box, /* first non standard character */ + cet_ucs4_cnt_iso_10367_box, /* number of values in table */ + + cet_ucs4_to_iso_10367_box_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_10367_box_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_10367_box_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x2551, 0x2550, 0x2554, 0x2557, 0x255a, 0x255d, 0x2560, 0x2563, + 0x2566, 0x2569, 0x256c, 0xe019, 0x2584, 0x2588, 0x25aa, -1, + 0x2502, 0x2500, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2591, 0x2592, 0x2593, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_5427.h b/cet/iso_5427.h new file mode 100644 index 000000000..7876a4336 --- /dev/null +++ b/cet/iso_5427.h @@ -0,0 +1,188 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_5427" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_5427_h +#define iso_5427_h + +#define cet_cs_name_iso_5427 "ISO_5427" + +const char *cet_cs_alias_iso_5427[] = +{ + "ISO_5427", "iso-ir-37", NULL +}; + +#define cet_ucs4_ofs_iso_5427 36 +#define cet_ucs4_cnt_iso_5427 92 + +const int cet_ucs4_map_iso_5427[cet_ucs4_cnt_iso_5427] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x044e, 0x0430, 0x0431, 0x0446, + 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x044f, 0x0440, 0x0441, + 0x0442, 0x0443, 0x0436, 0x0432, 0x044c, 0x044b, 0x0437, 0x0448, + 0x044d, 0x0449, 0x0447, 0x044a, 0x042e, 0x0410, 0x0411, 0x0426, + 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041a, + 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x042f, 0x0420, 0x0421, + 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, 0x042b, 0x0417, 0x0428, + 0x042d, 0x0429, 0x0427, 0x007f +}; + +#define cet_ucs4_to_iso_5427_ct 64 + +const cet_ucs4_link_t cet_ucs4_to_iso_5427_links[cet_ucs4_to_iso_5427_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0410, 0x61} /* capital letter a */, + {0x0411, 0x62} /* capital letter be */, + {0x0412, 0x77} /* capital letter ve */, + {0x0413, 0x67} /* capital letter ghe */, + {0x0414, 0x64} /* capital letter de */, + {0x0415, 0x65} /* capital letter ie */, + {0x0416, 0x76} /* capital letter zhe */, + {0x0417, 0x7a} /* capital letter ze */, + {0x0418, 0x69} /* capital letter i */, + {0x0419, 0x6a} /* capital letter short i */, + {0x041a, 0x6b} /* capital letter ka */, + {0x041b, 0x6c} /* capital letter el */, + {0x041c, 0x6d} /* capital letter em */, + {0x041d, 0x6e} /* capital letter en */, + {0x041e, 0x6f} /* capital letter o */, + {0x041f, 0x70} /* capital letter pe */, + {0x0420, 0x72} /* capital letter er */, + {0x0421, 0x73} /* capital letter es */, + {0x0422, 0x74} /* capital letter te */, + {0x0423, 0x75} /* capital letter u */, + {0x0424, 0x66} /* capital letter ef */, + {0x0425, 0x68} /* capital letter ha */, + {0x0426, 0x63} /* capital letter tse */, + {0x0427, 0x7e} /* capital letter che */, + {0x0428, 0x7b} /* capital letter sha */, + {0x0429, 0x7d} /* capital letter shcha */, + {0x042b, 0x79} /* capital letter yeru */, + {0x042c, 0x78} /* capital letter soft sign */, + {0x042d, 0x7c} /* capital letter e */, + {0x042e, 0x60} /* capital letter yu */, + {0x042f, 0x71} /* capital letter ya */, + {0x0430, 0x41} /* small letter a */, + {0x0431, 0x42} /* small letter be */, + {0x0432, 0x57} /* small letter ve */, + {0x0433, 0x47} /* small letter ghe */, + {0x0434, 0x44} /* small letter de */, + {0x0435, 0x45} /* small letter ie */, + {0x0436, 0x56} /* small letter zhe */, + {0x0437, 0x5a} /* small letter ze */, + {0x0438, 0x49} /* small letter i */, + {0x0439, 0x4a} /* small letter short i */, + {0x043a, 0x4b} /* small letter ka */, + {0x043b, 0x4c} /* small letter el */, + {0x043c, 0x4d} /* small letter em */, + {0x043d, 0x4e} /* small letter en */, + {0x043e, 0x4f} /* small letter o */, + {0x043f, 0x50} /* small letter pe */, + {0x0440, 0x52} /* small letter er */, + {0x0441, 0x53} /* small letter es */, + {0x0442, 0x54} /* small letter te */, + {0x0443, 0x55} /* small letter u */, + {0x0444, 0x46} /* small letter ef */, + {0x0445, 0x48} /* small letter ha */, + {0x0446, 0x43} /* small letter tse */, + {0x0447, 0x5e} /* small letter che */, + {0x0448, 0x5b} /* small letter sha */, + {0x0449, 0x5d} /* small letter shcha */, + {0x044a, 0x5f} /* small letter hard sign */, + {0x044b, 0x59} /* small letter yeru */, + {0x044c, 0x58} /* small letter soft sign */, + {0x044d, 0x5c} /* small letter e */, + {0x044e, 0x40} /* small letter yu */, + {0x044f, 0x51} /* small letter ya */ +}; + +/* +#define cet_ucs4_to_iso_5427_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_5427_extra[cet_ucs4_to_iso_5427_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_5427 = /* defined in cet.h */ +{ + cet_cs_name_iso_5427, /* name of character set */ + cet_cs_alias_iso_5427, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_5427, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_5427, /* first non standard character */ + cet_ucs4_cnt_iso_5427, /* number of values in table */ + + cet_ucs4_to_iso_5427_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_5427_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_5427_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_646_irv.h b/cet/iso_646_irv.h new file mode 100644 index 000000000..26be677db --- /dev/null +++ b/cet/iso_646_irv.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_646.irv" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_646_irv_h +#define iso_646_irv_h + +#define cet_cs_name_iso_646_irv "ISO_646.irv" + +const char *cet_cs_alias_iso_646_irv[] = +{ + "ISO_646.irv", "irv", "iso-ir-2", "ISO_646.irv:1983", + NULL +}; + +#define cet_ucs4_ofs_iso_646_irv 36 +#define cet_ucs4_cnt_iso_646_irv 92 + +const int cet_ucs4_map_iso_646_irv[cet_ucs4_cnt_iso_646_irv] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_iso_646_irv_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_iso_646_irv_links[cet_ucs4_to_iso_646_irv_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_iso_646_irv_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_646_irv_extra[cet_ucs4_to_iso_646_irv_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_646_irv = /* defined in cet.h */ +{ + cet_cs_name_iso_646_irv, /* name of character set */ + cet_cs_alias_iso_646_irv, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_646_irv, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_646_irv, /* first non standard character */ + cet_ucs4_cnt_iso_646_irv, /* number of values in table */ + + cet_ucs4_to_iso_646_irv_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_646_irv_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_646_irv_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_6937_2_25.h b/cet/iso_6937_2_25.h new file mode 100644 index 000000000..fbc7a8e4d --- /dev/null +++ b/cet/iso_6937_2_25.h @@ -0,0 +1,166 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_6937-2-25" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_6937_2_25_h +#define iso_6937_2_25_h + +#define cet_cs_name_iso_6937_2_25 "ISO_6937-2-25" + +const char *cet_cs_alias_iso_6937_2_25[] = +{ + "ISO_6937-2-25", "iso-ir-152", NULL +}; + +#define cet_ucs4_ofs_iso_6937_2_25 36 +#define cet_ucs4_cnt_iso_6937_2_25 218 + +const int cet_ucs4_map_iso_6937_2_25[cet_ucs4_cnt_iso_6937_2_25] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0x201c, -1, + 0x2190, 0x2191, 0x2192, 0x2193, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0x201d, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x2122, 0x266a, -1, -1, -1, -1, -1, -1, + 0x215b, 0x215c, 0x215d, 0x215e, 0x2126, -1, -1, -1, + -1, -1, 0x0132, 0x013f, -1, -1, 0x0152, -1, + 0x0174, 0x0176, 0x0178, 0x0149, -1, -1, -1, -1, + -1, -1, 0x0133, 0x0140, -1, -1, 0x0153, -1, + 0x0175, 0x0177 +}; + +#define cet_ucs4_to_iso_6937_2_25_ct 26 + +const cet_ucs4_link_t cet_ucs4_to_iso_6937_2_25_links[cet_ucs4_to_iso_6937_2_25_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0132, 0xe6} /* capital ligature ij */, + {0x0133, 0xf6} /* small ligature ij */, + {0x013f, 0xe7} /* capital letter l with middle dot */, + {0x0140, 0xf7} /* small letter l with middle dot */, + {0x0149, 0xef} /* small letter n preceded by apostrophe */, + {0x0152, 0xea} /* capital ligature oe */, + {0x0153, 0xfa} /* small ligature oe */, + {0x0174, 0xec} /* capital letter w with circumflex */, + {0x0175, 0xfc} /* small letter w with circumflex */, + {0x0176, 0xed} /* capital letter y with circumflex */, + {0x0177, 0xfd} /* small letter y with circumflex */, + {0x0178, 0xee} /* capital letter y with diaeresis */, + {0x201c, 0xaa} /* double quotation mark */, + {0x201d, 0xba} /* double quotation mark */, + {0x2122, 0xd4} /* mark sign */, + {0x2126, 0xe0} /* sign */, + {0x215b, 0xdc} /* fraction one eighth */, + {0x215c, 0xdd} /* fraction three eighths */, + {0x215d, 0xde} /* fraction five eighths */, + {0x215e, 0xdf} /* fraction seven eighths */, + {0x2190, 0xac} /* arrow */, + {0x2191, 0xad} /* arrow */, + {0x2192, 0xae} /* arrow */, + {0x2193, 0xaf} /* arrow */, + {0x266a, 0xd5} /* note */ +}; + +/* +#define cet_ucs4_to_iso_6937_2_25_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_6937_2_25_extra[cet_ucs4_to_iso_6937_2_25_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_6937_2_25 = /* defined in cet.h */ +{ + cet_cs_name_iso_6937_2_25, /* name of character set */ + cet_cs_alias_iso_6937_2_25, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_6937_2_25, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_6937_2_25, /* first non standard character */ + cet_ucs4_cnt_iso_6937_2_25, /* number of values in table */ + + cet_ucs4_to_iso_6937_2_25_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_6937_2_25_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_6937_2_25_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x201c, -1, 0x2190, 0x2191, 0x2192, 0x2193, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x201d, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 0x2122, 0x266a, -1, -1, + -1, -1, -1, -1, 0x215b, 0x215c, 0x215d, 0x215e, + 0x2126, -1, -1, -1, -1, -1, 0x0132, 0x013f, + -1, -1, 0x0152, -1, 0x0174, 0x0176, 0x0178, 0x0149, + -1, -1, -1, -1, -1, -1, 0x0133, 0x0140, + -1, -1, 0x0153, -1, 0x0175, 0x0177, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_1.h b/cet/iso_8859_1.h new file mode 100644 index 000000000..8dab41ff0 --- /dev/null +++ b/cet/iso_8859_1.h @@ -0,0 +1,111 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_1_h +#define iso_8859_1_h + +#define cet_cs_name_iso_8859_1 "ISO-8859-1" + +const char *cet_cs_alias_iso_8859_1[] = +{ + "ISO-8859-1", "819", "CP819", "csISOLatin1", + "IBM819", "ISO8859-1", "iso-ir-100", "ISO_8859-1", + "ISO_8859-1:1987", "l1", "lat1", "latin1", + "Latin-1", NULL +}; + +#define cet_ucs4_ofs_iso_8859_1 256 +#define cet_ucs4_cnt_iso_8859_1 1 + +const int cet_ucs4_map_iso_8859_1[cet_ucs4_cnt_iso_8859_1]; + +#define cet_ucs4_to_iso_8859_1_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_1_links[cet_ucs4_to_iso_8859_1_ct]; + +/* +#define cet_ucs4_to_iso_8859_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_1_extra[cet_ucs4_to_iso_8859_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_1 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_1, /* name of character set */ + cet_cs_alias_iso_8859_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_1, /* first non standard character */ + cet_ucs4_cnt_iso_8859_1, /* number of values in table */ + + cet_ucs4_to_iso_8859_1_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_10.h b/cet/iso_8859_10.h new file mode 100644 index 000000000..8adfc7132 --- /dev/null +++ b/cet/iso_8859_10.h @@ -0,0 +1,172 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-10" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_10_h +#define iso_8859_10_h + +#define cet_cs_name_iso_8859_10 "ISO-8859-10" + +const char *cet_cs_alias_iso_8859_10[] = +{ + "ISO-8859-10", "csISOLatin6", "ISO8859-10", "iso-ir-157", + "ISO_8859-10", "ISO_8859-10:1992", "ISO_8859-10:1993", + "l6", "lat6", "latin6", NULL +}; + +#define cet_ucs4_ofs_iso_8859_10 161 +#define cet_ucs4_cnt_iso_8859_10 95 + +const int cet_ucs4_map_iso_8859_10[cet_ucs4_cnt_iso_8859_10] = +{ + 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, 0x013b, + 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, 0x00b0, + 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, + 0x0111, 0x0161, 0x0167, 0x017e, 0x2014, 0x016b, 0x014b, 0x0100, + 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, + 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, 0x00d0, + 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, + 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x0101, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, + 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, 0x00f0, + 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, + 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138 +}; + +#define cet_ucs4_to_iso_8859_10_ct 46 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_10_links[cet_ucs4_to_iso_8859_10_ct] = +{ + {0x0100, 0xc0} /* capital letter a with macron */, + {0x0101, 0xe0} /* small letter a with macron */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0110, 0xa9} /* capital letter d with stroke */, + {0x0111, 0xb9} /* small letter d with stroke */, + {0x0112, 0xa2} /* capital letter e with macron */, + {0x0113, 0xb2} /* small letter e with macron */, + {0x0116, 0xcc} /* capital letter e with dot above */, + {0x0117, 0xec} /* small letter e with dot above */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x0122, 0xa3} /* capital letter g with cedilla */, + {0x0123, 0xb3} /* small letter g with cedilla */, + {0x0128, 0xa5} /* capital letter i with tilde */, + {0x0129, 0xb5} /* small letter i with tilde */, + {0x012a, 0xa4} /* capital letter i with macron */, + {0x012b, 0xb4} /* small letter i with macron */, + {0x012e, 0xc7} /* capital letter i with ogonek */, + {0x012f, 0xe7} /* small letter i with ogonek */, + {0x0136, 0xa6} /* capital letter k with cedilla */, + {0x0137, 0xb6} /* small letter k with cedilla */, + {0x0138, 0xff} /* small letter kra (greenlandic) */, + {0x013b, 0xa8} /* capital letter l with cedilla */, + {0x013c, 0xb8} /* small letter l with cedilla */, + {0x0145, 0xd1} /* capital letter n with cedilla */, + {0x0146, 0xf1} /* small letter n with cedilla */, + {0x014a, 0xaf} /* capital letter eng (lappish) */, + {0x014b, 0xbf} /* small letter eng (lappish) */, + {0x014c, 0xd2} /* capital letter o with macron */, + {0x014d, 0xf2} /* small letter o with macron */, + {0x0160, 0xaa} /* capital letter s with caron */, + {0x0161, 0xba} /* small letter s with caron */, + {0x0166, 0xab} /* capital letter t with stroke */, + {0x0167, 0xbb} /* small letter t with stroke */, + {0x0168, 0xd7} /* capital letter u with tilde */, + {0x0169, 0xf7} /* small letter u with tilde */, + {0x016a, 0xae} /* capital letter u with macron */, + {0x016b, 0xbe} /* small letter u with macron */, + {0x0172, 0xd9} /* capital letter u with ogonek */, + {0x0173, 0xf9} /* small letter u with ogonek */, + {0x017d, 0xac} /* capital letter z with caron */, + {0x017e, 0xbc} /* small letter z with caron */, + {0x2014, 0xbd} /* dash */ +}; + +/* +#define cet_ucs4_to_iso_8859_10_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_10_extra[cet_ucs4_to_iso_8859_10_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_10 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_10, /* name of character set */ + cet_cs_alias_iso_8859_10, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_10, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_10, /* first non standard character */ + cet_ucs4_cnt_iso_8859_10, /* number of values in table */ + + cet_ucs4_to_iso_8859_10_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_10_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_10_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, + 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, + 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, + 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2014, 0x016b, 0x014b, + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138 +}; +*/ + +#endif diff --git a/cet/iso_8859_13.h b/cet/iso_8859_13.h new file mode 100644 index 000000000..e67175e09 --- /dev/null +++ b/cet/iso_8859_13.h @@ -0,0 +1,175 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-13" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_13_h +#define iso_8859_13_h + +#define cet_cs_name_iso_8859_13 "ISO-8859-13" + +const char *cet_cs_alias_iso_8859_13[] = +{ + "ISO-8859-13", "ISO8859-13", "iso-baltic", "ISO-IR-179", + "iso-ir-179a", "ISO_8859-13", "ISO_8859-13:1998", + "l7", "lat7", "latin7", NULL +}; + +#define cet_ucs4_ofs_iso_8859_13 165 +#define cet_ucs4_cnt_iso_8859_13 91 + +const int cet_ucs4_map_iso_8859_13[cet_ucs4_cnt_iso_8859_13] = +{ + 0x201e, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, + 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, + 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, + 0x00bd, 0x00be, 0x00bf, 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, + 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, + 0x0136, 0x012a, 0x013b, 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, + 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, + 0x017b, 0x017d, 0x00df, 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, + 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, + 0x0137, 0x012b, 0x013c, 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, + 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, + 0x017c, 0x017e, 0x2019 +}; + +#define cet_ucs4_to_iso_8859_13_ct 49 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_13_links[cet_ucs4_to_iso_8859_13_ct] = +{ + {0x0100, 0xc2} /* capital letter a with macron */, + {0x0101, 0xe2} /* small letter a with macron */, + {0x0104, 0xc0} /* capital letter a with ogonek */, + {0x0105, 0xe0} /* small letter a with ogonek */, + {0x0106, 0xc3} /* capital letter c with acute */, + {0x0107, 0xe3} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0112, 0xc7} /* capital letter e with macron */, + {0x0113, 0xe7} /* small letter e with macron */, + {0x0116, 0xcb} /* capital letter e with dot above */, + {0x0117, 0xeb} /* small letter e with dot above */, + {0x0118, 0xc6} /* capital letter e with ogonek */, + {0x0119, 0xe6} /* small letter e with ogonek */, + {0x0122, 0xcc} /* capital letter g with cedilla */, + {0x0123, 0xec} /* small letter g with cedilla */, + {0x012a, 0xce} /* capital letter i with macron */, + {0x012b, 0xee} /* small letter i with macron */, + {0x012e, 0xc1} /* capital letter i with ogonek */, + {0x012f, 0xe1} /* small letter i with ogonek */, + {0x0136, 0xcd} /* capital letter k with cedilla */, + {0x0137, 0xed} /* small letter k with cedilla */, + {0x013b, 0xcf} /* capital letter l with cedilla */, + {0x013c, 0xef} /* small letter l with cedilla */, + {0x0141, 0xd9} /* capital letter l with stroke */, + {0x0142, 0xf9} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0145, 0xd2} /* capital letter n with cedilla */, + {0x0146, 0xf2} /* small letter n with cedilla */, + {0x014c, 0xd4} /* capital letter o with macron */, + {0x014d, 0xf4} /* small letter o with macron */, + {0x015a, 0xda} /* capital letter s with acute */, + {0x015b, 0xfa} /* small letter s with acute */, + {0x0160, 0xd0} /* capital letter s with caron */, + {0x0161, 0xf0} /* small letter s with caron */, + {0x016a, 0xdb} /* capital letter u with macron */, + {0x016b, 0xfb} /* small letter u with macron */, + {0x0172, 0xd8} /* capital letter u with ogonek */, + {0x0173, 0xf8} /* small letter u with ogonek */, + {0x0179, 0xca} /* capital letter z with acute */, + {0x017a, 0xea} /* small letter z with acute */, + {0x017b, 0xdd} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xde} /* capital letter z with caron */, + {0x017e, 0xfe} /* small letter z with caron */, + {0x2019, 0xff} /* single quotation mark */, + {0x201c, 0xb4} /* double quotation mark */, + {0x201e, 0xa5} /* low-9 quotation mark */ +}; + +/* +#define cet_ucs4_to_iso_8859_13_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_13_extra[cet_ucs4_to_iso_8859_13_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_13 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_13, /* name of character set */ + cet_cs_alias_iso_8859_13, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_13, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_13, /* first non standard character */ + cet_ucs4_cnt_iso_8859_13, /* number of values in table */ + + cet_ucs4_to_iso_8859_13_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_13_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_13_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019 +}; +*/ + +#endif diff --git a/cet/iso_8859_14.h b/cet/iso_8859_14.h new file mode 100644 index 000000000..fb47dd817 --- /dev/null +++ b/cet/iso_8859_14.h @@ -0,0 +1,157 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-14" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_14_h +#define iso_8859_14_h + +#define cet_cs_name_iso_8859_14 "ISO-8859-14" + +const char *cet_cs_alias_iso_8859_14[] = +{ + "ISO-8859-14", "ISO8859-14", "iso-celtic", "iso-ir-199", + "ISO_8859-14", "ISO_8859-14:1998", "l8", "lat8", "latin8", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_14 161 +#define cet_ucs4_cnt_iso_8859_14 95 + +const int cet_ucs4_map_iso_8859_14[cet_ucs4_cnt_iso_8859_14] = +{ + 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, + 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x1e61, 0x1e1e, + 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, + 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x0178, 0x00c0, + 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x0174, + 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, + 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, 0x00e0, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, + 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x0175, + 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, + 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff +}; + +#define cet_ucs4_to_iso_8859_14_ct 31 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_14_links[cet_ucs4_to_iso_8859_14_ct] = +{ + {0x010a, 0xa4} /* capital letter c with dot above */, + {0x010b, 0xa5} /* small letter c with dot above */, + {0x0120, 0xb2} /* capital letter g with dot above */, + {0x0121, 0xb3} /* small letter g with dot above */, + {0x0174, 0xd0} /* capital letter w with circumflex */, + {0x0175, 0xf0} /* small letter w with circumflex */, + {0x0176, 0xde} /* capital letter y with circumflex */, + {0x0177, 0xfe} /* small letter y with circumflex */, + {0x0178, 0xbf} /* capital letter y with diaeresis */, + {0x1e02, 0xa1} /* capital letter b with dot above */, + {0x1e03, 0xa2} /* small letter b with dot above */, + {0x1e0a, 0xa6} /* capital letter d with dot above */, + {0x1e0b, 0xab} /* small letter d with dot above */, + {0x1e1e, 0xb0} /* capital letter f with dot above */, + {0x1e1f, 0xb1} /* small letter f with dot above */, + {0x1e40, 0xb4} /* capital letter m with dot above */, + {0x1e41, 0xb5} /* small letter m with dot above */, + {0x1e56, 0xb7} /* capital letter p with dot above */, + {0x1e57, 0xb9} /* small letter p with dot above */, + {0x1e60, 0xbb} /* capital letter s with dot above */, + {0x1e61, 0xaf} /* small letter s with dot above */, + {0x1e6a, 0xd7} /* capital letter t with dot above */, + {0x1e6b, 0xf7} /* small letter t with dot above */, + {0x1e80, 0xa8} /* capital letter w with grave */, + {0x1e81, 0xb8} /* small letter w with grave */, + {0x1e82, 0xaa} /* capital letter w with acute */, + {0x1e83, 0xba} /* small letter w with acute */, + {0x1e84, 0xbd} /* capital letter w with diaeresis */, + {0x1e85, 0xbe} /* small letter w with diaeresis */, + {0x1ef2, 0xac} /* capital letter y with grave */, + {0x1ef3, 0xbc} /* small letter y with grave */ +}; + +/* +#define cet_ucs4_to_iso_8859_14_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_14_extra[cet_ucs4_to_iso_8859_14_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_14 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_14, /* name of character set */ + cet_cs_alias_iso_8859_14, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_14, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_14, /* first non standard character */ + cet_ucs4_cnt_iso_8859_14, /* number of values in table */ + + cet_ucs4_to_iso_8859_14_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_14_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_14_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, + 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x1e61, + 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x0178, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_15.h b/cet/iso_8859_15.h new file mode 100644 index 000000000..88750962b --- /dev/null +++ b/cet/iso_8859_15.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-15" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_15_h +#define iso_8859_15_h + +#define cet_cs_name_iso_8859_15 "ISO-8859-15" + +const char *cet_cs_alias_iso_8859_15[] = +{ + "ISO-8859-15", "ISO8859-15", "iso-ir-203", "ISO_8859-15", + "ISO_8859-15:1998", "l9", "lat9", "latin9", NULL +}; + +#define cet_ucs4_ofs_iso_8859_15 164 +#define cet_ucs4_cnt_iso_8859_15 92 + +const int cet_ucs4_map_iso_8859_15[cet_ucs4_cnt_iso_8859_15] = +{ + 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, + 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, + 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, + 0x0152, 0x0153, 0x0178, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, + 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, + 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, + 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, + 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, + 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, + 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, + 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_iso_8859_15_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_15_links[cet_ucs4_to_iso_8859_15_ct] = +{ + {0x0152, 0xbc} /* capital ligature oe */, + {0x0153, 0xbd} /* small ligature oe */, + {0x0160, 0xa6} /* capital letter s with caron */, + {0x0161, 0xa8} /* small letter s with caron */, + {0x0178, 0xbe} /* capital letter y with diaeresis */, + {0x017d, 0xb4} /* capital letter z with caron */, + {0x017e, 0xb8} /* small letter z with caron */, + {0x20ac, 0xa4} /* euro */ +}; + +/* +#define cet_ucs4_to_iso_8859_15_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_15_extra[cet_ucs4_to_iso_8859_15_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_15 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_15, /* name of character set */ + cet_cs_alias_iso_8859_15, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_15, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_15, /* first non standard character */ + cet_ucs4_cnt_iso_8859_15, /* number of values in table */ + + cet_ucs4_to_iso_8859_15_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_15_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_15_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, + 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, + 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_2.h b/cet/iso_8859_2.h new file mode 100644 index 000000000..6e348cc06 --- /dev/null +++ b/cet/iso_8859_2.h @@ -0,0 +1,183 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_2_h +#define iso_8859_2_h + +#define cet_cs_name_iso_8859_2 "ISO-8859-2" + +const char *cet_cs_alias_iso_8859_2[] = +{ + "ISO-8859-2", "912", "CP912", "csISOLatin2", + "IBM912", "ISO8859-2", "iso-ir-101", "ISO_8859-2", + "ISO_8859-2:1987", "l2", "lat2", "latin2", NULL +}; + +#define cet_ucs4_ofs_iso_8859_2 161 +#define cet_ucs4_cnt_iso_8859_2 95 + +const int cet_ucs4_map_iso_8859_2[cet_ucs4_cnt_iso_8859_2] = +{ + 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, + 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, 0x00b0, + 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, + 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, 0x0154, + 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, + 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, 0x0110, + 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, + 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, 0x0155, + 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, + 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, 0x0111, + 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, + 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; + +#define cet_ucs4_to_iso_8859_2_ct 57 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_2_links[cet_ucs4_to_iso_8859_2_ct] = +{ + {0x0102, 0xc3} /* capital letter a with breve */, + {0x0103, 0xe3} /* small letter a with breve */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x0106, 0xc6} /* capital letter c with acute */, + {0x0107, 0xe6} /* small letter c with acute */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x010e, 0xcf} /* capital letter d with caron */, + {0x010f, 0xef} /* small letter d with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011a, 0xcc} /* capital letter e with caron */, + {0x011b, 0xec} /* small letter e with caron */, + {0x0139, 0xc5} /* capital letter l with acute */, + {0x013a, 0xe5} /* small letter l with acute */, + {0x013d, 0xa5} /* capital letter l with caron */, + {0x013e, 0xb5} /* small letter l with caron */, + {0x0141, 0xa3} /* capital letter l with stroke */, + {0x0142, 0xb3} /* small letter l with stroke */, + {0x0143, 0xd1} /* capital letter n with acute */, + {0x0144, 0xf1} /* small letter n with acute */, + {0x0147, 0xd2} /* capital letter n with caron */, + {0x0148, 0xf2} /* small letter n with caron */, + {0x0150, 0xd5} /* capital letter o with double acute */, + {0x0151, 0xf5} /* small letter o with double acute */, + {0x0154, 0xc0} /* capital letter r with acute */, + {0x0155, 0xe0} /* small letter r with acute */, + {0x0158, 0xd8} /* capital letter r with caron */, + {0x0159, 0xf8} /* small letter r with caron */, + {0x015a, 0xa6} /* capital letter s with acute */, + {0x015b, 0xb6} /* small letter s with acute */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x0160, 0xa9} /* capital letter s with caron */, + {0x0161, 0xb9} /* small letter s with caron */, + {0x0162, 0xde} /* capital letter t with cedilla */, + {0x0163, 0xfe} /* small letter t with cedilla */, + {0x0164, 0xab} /* capital letter t with caron */, + {0x0165, 0xbb} /* small letter t with caron */, + {0x016e, 0xd9} /* capital letter u with ring above */, + {0x016f, 0xf9} /* small letter u with ring above */, + {0x0170, 0xdb} /* capital letter u with double acute */, + {0x0171, 0xfb} /* small letter u with double acute */, + {0x0179, 0xac} /* capital letter z with acute */, + {0x017a, 0xbc} /* small letter z with acute */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x017d, 0xae} /* capital letter z with caron */, + {0x017e, 0xbe} /* small letter z with caron */, + {0x02c7, 0xb7} /* caron */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */, + {0x02dd, 0xbd} /* acute accent */ +}; + +/* +#define cet_ucs4_to_iso_8859_2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_2_extra[cet_ucs4_to_iso_8859_2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_2 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_2, /* name of character set */ + cet_cs_alias_iso_8859_2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_2, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_2, /* first non standard character */ + cet_ucs4_cnt_iso_8859_2, /* number of values in table */ + + cet_ucs4_to_iso_8859_2_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9 +}; +*/ + +#endif diff --git a/cet/iso_8859_3.h b/cet/iso_8859_3.h new file mode 100644 index 000000000..1a264d196 --- /dev/null +++ b/cet/iso_8859_3.h @@ -0,0 +1,154 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-3" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_3_h +#define iso_8859_3_h + +#define cet_cs_name_iso_8859_3 "ISO-8859-3" + +const char *cet_cs_alias_iso_8859_3[] = +{ + "ISO-8859-3", "csISOLatin3", "ISO8859-3", "iso-ir-109", + "ISO_8859-3", "ISO_8859-3:1988", "l3", "lat3", "latin3", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_3 161 +#define cet_ucs4_cnt_iso_8859_3 95 + +const int cet_ucs4_map_iso_8859_3[cet_ucs4_cnt_iso_8859_3] = +{ + 0x0126, 0x02d8, 0x00a3, 0x00a4, -1, 0x0124, 0x00a7, 0x00a8, + 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, -1, 0x017b, 0x00b0, + 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, + 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, -1, 0x017c, 0x00c0, + 0x00c1, 0x00c2, -1, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, -1, + 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, + 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, 0x00e0, + 0x00e1, 0x00e2, -1, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, + 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, -1, + 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, + 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9 +}; + +#define cet_ucs4_to_iso_8859_3_ct 28 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_3_links[cet_ucs4_to_iso_8859_3_ct] = +{ + {0x0108, 0xc6} /* capital letter c with circumflex */, + {0x0109, 0xe6} /* small letter c with circumflex */, + {0x010a, 0xc5} /* capital letter c with dot above */, + {0x010b, 0xe5} /* small letter c with dot above */, + {0x011c, 0xd8} /* capital letter g with circumflex */, + {0x011d, 0xf8} /* small letter g with circumflex */, + {0x011e, 0xab} /* capital letter g with breve */, + {0x011f, 0xbb} /* small letter g with breve */, + {0x0120, 0xd5} /* capital letter g with dot above */, + {0x0121, 0xf5} /* small letter g with dot above */, + {0x0124, 0xa6} /* capital letter h with circumflex */, + {0x0125, 0xb6} /* small letter h with circumflex */, + {0x0126, 0xa1} /* capital letter h with stroke */, + {0x0127, 0xb1} /* small letter h with stroke */, + {0x0130, 0xa9} /* capital letter i with dot above */, + {0x0131, 0xb9} /* small letter i dotless */, + {0x0134, 0xac} /* capital letter j with circumflex */, + {0x0135, 0xbc} /* small letter j with circumflex */, + {0x015c, 0xde} /* capital letter s with circumflex */, + {0x015d, 0xfe} /* small letter s with circumflex */, + {0x015e, 0xaa} /* capital letter s with cedilla */, + {0x015f, 0xba} /* small letter s with cedilla */, + {0x016c, 0xdd} /* capital letter u with breve */, + {0x016d, 0xfd} /* small letter u with breve */, + {0x017b, 0xaf} /* capital letter z with dot above */, + {0x017c, 0xbf} /* small letter z with dot above */, + {0x02d8, 0xa2} /* breve */, + {0x02d9, 0xff} /* above */ +}; + +/* +#define cet_ucs4_to_iso_8859_3_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_3_extra[cet_ucs4_to_iso_8859_3_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_3 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_3, /* name of character set */ + cet_cs_alias_iso_8859_3, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_3, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_3, /* first non standard character */ + cet_ucs4_cnt_iso_8859_3, /* number of values in table */ + + cet_ucs4_to_iso_8859_3_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_3_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_3_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, -1, 0x0124, 0x00a7, + 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, -1, 0x017b, + 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, + 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, -1, 0x017c, + 0x00c0, 0x00c1, 0x00c2, -1, 0x00c4, 0x010a, 0x0108, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + -1, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, + 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, + 0x00e0, 0x00e1, 0x00e2, -1, 0x00e4, 0x010b, 0x0109, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + -1, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, + 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9 +}; +*/ + +#endif diff --git a/cet/iso_8859_4.h b/cet/iso_8859_4.h new file mode 100644 index 000000000..e9d8a6e04 --- /dev/null +++ b/cet/iso_8859_4.h @@ -0,0 +1,176 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-4" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_4_h +#define iso_8859_4_h + +#define cet_cs_name_iso_8859_4 "ISO-8859-4" + +const char *cet_cs_alias_iso_8859_4[] = +{ + "ISO-8859-4", "csISOLatin4", "ISO8859-4", "iso-ir-110", + "ISO_8859-4", "ISO_8859-4:1988", "l4", "lat4", "latin4", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_4 161 +#define cet_ucs4_cnt_iso_8859_4 95 + +const int cet_ucs4_map_iso_8859_4[cet_ucs4_cnt_iso_8859_4] = +{ + 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, 0x00a8, + 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, 0x00b0, + 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, + 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, 0x0100, + 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, + 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, 0x0110, + 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, + 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, 0x0101, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, + 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, 0x0111, + 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, + 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9 +}; + +#define cet_ucs4_to_iso_8859_4_ct 50 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_4_links[cet_ucs4_to_iso_8859_4_ct] = +{ + {0x0100, 0xc0} /* capital letter a with macron */, + {0x0101, 0xe0} /* small letter a with macron */, + {0x0104, 0xa1} /* capital letter a with ogonek */, + {0x0105, 0xb1} /* small letter a with ogonek */, + {0x010c, 0xc8} /* capital letter c with caron */, + {0x010d, 0xe8} /* small letter c with caron */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0112, 0xaa} /* capital letter e with macron */, + {0x0113, 0xba} /* small letter e with macron */, + {0x0116, 0xcc} /* capital letter e with dot above */, + {0x0117, 0xec} /* small letter e with dot above */, + {0x0118, 0xca} /* capital letter e with ogonek */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x0122, 0xab} /* capital letter g with cedilla */, + {0x0123, 0xbb} /* small letter g with cedilla */, + {0x0128, 0xa5} /* capital letter i with tilde */, + {0x0129, 0xb5} /* small letter i with tilde */, + {0x012a, 0xcf} /* capital letter i with macron */, + {0x012b, 0xef} /* small letter i with macron */, + {0x012e, 0xc7} /* capital letter i with ogonek */, + {0x012f, 0xe7} /* small letter i with ogonek */, + {0x0136, 0xd3} /* capital letter k with cedilla */, + {0x0137, 0xf3} /* small letter k with cedilla */, + {0x0138, 0xa2} /* small letter kra (greenlandic) */, + {0x013b, 0xa6} /* capital letter l with cedilla */, + {0x013c, 0xb6} /* small letter l with cedilla */, + {0x0145, 0xd1} /* capital letter n with cedilla */, + {0x0146, 0xf1} /* small letter n with cedilla */, + {0x014a, 0xbd} /* capital letter eng (lappish) */, + {0x014b, 0xbf} /* small letter eng (lappish) */, + {0x014c, 0xd2} /* capital letter o with macron */, + {0x014d, 0xf2} /* small letter o with macron */, + {0x0156, 0xa3} /* capital letter r with cedilla */, + {0x0157, 0xb3} /* small letter r with cedilla */, + {0x0160, 0xa9} /* capital letter s with caron */, + {0x0161, 0xb9} /* small letter s with caron */, + {0x0166, 0xac} /* capital letter t with stroke */, + {0x0167, 0xbc} /* small letter t with stroke */, + {0x0168, 0xdd} /* capital letter u with tilde */, + {0x0169, 0xfd} /* small letter u with tilde */, + {0x016a, 0xde} /* capital letter u with macron */, + {0x016b, 0xfe} /* small letter u with macron */, + {0x0172, 0xd9} /* capital letter u with ogonek */, + {0x0173, 0xf9} /* small letter u with ogonek */, + {0x017d, 0xae} /* capital letter z with caron */, + {0x017e, 0xbe} /* small letter z with caron */, + {0x02c7, 0xb7} /* caron */, + {0x02d9, 0xff} /* above */, + {0x02db, 0xb2} /* ogonek */ +}; + +/* +#define cet_ucs4_to_iso_8859_4_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_4_extra[cet_ucs4_to_iso_8859_4_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_4 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_4, /* name of character set */ + cet_cs_alias_iso_8859_4, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_4, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_4, /* first non standard character */ + cet_ucs4_cnt_iso_8859_4, /* number of values in table */ + + cet_ucs4_to_iso_8859_4_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_4_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_4_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, + 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, + 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, + 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, + 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9 +}; +*/ + +#endif diff --git a/cet/iso_8859_5.h b/cet/iso_8859_5.h new file mode 100644 index 000000000..c70e4919a --- /dev/null +++ b/cet/iso_8859_5.h @@ -0,0 +1,219 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-5" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_5_h +#define iso_8859_5_h + +#define cet_cs_name_iso_8859_5 "ISO-8859-5" + +const char *cet_cs_alias_iso_8859_5[] = +{ + "ISO-8859-5", "csISOLatinCyrillic", "cyrillic", "ISO8859-5", + "iso-ir-144", "ISO_8859-5", "ISO_8859-5:1988", NULL +}; + +#define cet_ucs4_ofs_iso_8859_5 161 +#define cet_ucs4_cnt_iso_8859_5 95 + +const int cet_ucs4_map_iso_8859_5[cet_ucs4_cnt_iso_8859_5] = +{ + 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, 0x0410, + 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, + 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, + 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, + 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, + 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, + 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, + 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x2116, + 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f +}; + +#define cet_ucs4_to_iso_8859_5_ct 94 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_5_links[cet_ucs4_to_iso_8859_5_ct] = +{ + {0x00a7, 0xfd} /* sign */, + {0x0401, 0xa1} /* capital letter io */, + {0x0402, 0xa2} /* capital letter dje (serbocroatian) */, + {0x0403, 0xa3} /* capital letter gje (macedonian) */, + {0x0404, 0xa4} /* capital letter ukrainian ie */, + {0x0405, 0xa5} /* capital letter dze (macedonian) */, + {0x0406, 0xa6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xa7} /* capital letter yi (ukrainian) */, + {0x0408, 0xa8} /* capital letter je */, + {0x0409, 0xa9} /* capital letter lje */, + {0x040a, 0xaa} /* capital letter nje */, + {0x040b, 0xab} /* capital letter tshe (serbocroatian) */, + {0x040c, 0xac} /* capital letter kje (macedonian) */, + {0x040e, 0xae} /* capital letter short u (byelorussian) */, + {0x040f, 0xaf} /* capital letter dzhe */, + {0x0410, 0xb0} /* capital letter a */, + {0x0411, 0xb1} /* capital letter be */, + {0x0412, 0xb2} /* capital letter ve */, + {0x0413, 0xb3} /* capital letter ghe */, + {0x0414, 0xb4} /* capital letter de */, + {0x0415, 0xb5} /* capital letter ie */, + {0x0416, 0xb6} /* capital letter zhe */, + {0x0417, 0xb7} /* capital letter ze */, + {0x0418, 0xb8} /* capital letter i */, + {0x0419, 0xb9} /* capital letter short i */, + {0x041a, 0xba} /* capital letter ka */, + {0x041b, 0xbb} /* capital letter el */, + {0x041c, 0xbc} /* capital letter em */, + {0x041d, 0xbd} /* capital letter en */, + {0x041e, 0xbe} /* capital letter o */, + {0x041f, 0xbf} /* capital letter pe */, + {0x0420, 0xc0} /* capital letter er */, + {0x0421, 0xc1} /* capital letter es */, + {0x0422, 0xc2} /* capital letter te */, + {0x0423, 0xc3} /* capital letter u */, + {0x0424, 0xc4} /* capital letter ef */, + {0x0425, 0xc5} /* capital letter ha */, + {0x0426, 0xc6} /* capital letter tse */, + {0x0427, 0xc7} /* capital letter che */, + {0x0428, 0xc8} /* capital letter sha */, + {0x0429, 0xc9} /* capital letter shcha */, + {0x042a, 0xca} /* capital letter hard sign */, + {0x042b, 0xcb} /* capital letter yeru */, + {0x042c, 0xcc} /* capital letter soft sign */, + {0x042d, 0xcd} /* capital letter e */, + {0x042e, 0xce} /* capital letter yu */, + {0x042f, 0xcf} /* capital letter ya */, + {0x0430, 0xd0} /* small letter a */, + {0x0431, 0xd1} /* small letter be */, + {0x0432, 0xd2} /* small letter ve */, + {0x0433, 0xd3} /* small letter ghe */, + {0x0434, 0xd4} /* small letter de */, + {0x0435, 0xd5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xd7} /* small letter ze */, + {0x0438, 0xd8} /* small letter i */, + {0x0439, 0xd9} /* small letter short i */, + {0x043a, 0xda} /* small letter ka */, + {0x043b, 0xdb} /* small letter el */, + {0x043c, 0xdc} /* small letter em */, + {0x043d, 0xdd} /* small letter en */, + {0x043e, 0xde} /* small letter o */, + {0x043f, 0xdf} /* small letter pe */, + {0x0440, 0xe0} /* small letter er */, + {0x0441, 0xe1} /* small letter es */, + {0x0442, 0xe2} /* small letter te */, + {0x0443, 0xe3} /* small letter u */, + {0x0444, 0xe4} /* small letter ef */, + {0x0445, 0xe5} /* small letter ha */, + {0x0446, 0xe6} /* small letter tse */, + {0x0447, 0xe7} /* small letter che */, + {0x0448, 0xe8} /* small letter sha */, + {0x0449, 0xe9} /* small letter shcha */, + {0x044a, 0xea} /* small letter hard sign */, + {0x044b, 0xeb} /* small letter yeru */, + {0x044c, 0xec} /* small letter soft sign */, + {0x044d, 0xed} /* small letter e */, + {0x044e, 0xee} /* small letter yu */, + {0x044f, 0xef} /* small letter ya */, + {0x0451, 0xf1} /* small letter io */, + {0x0452, 0xf2} /* small letter dje (serbocroatian) */, + {0x0453, 0xf3} /* small letter gje (macedonian) */, + {0x0454, 0xf4} /* small letter ukrainian ie */, + {0x0455, 0xf5} /* small letter dze (macedonian) */, + {0x0456, 0xf6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xf7} /* small letter yi (ukrainian) */, + {0x0458, 0xf8} /* small letter je */, + {0x0459, 0xf9} /* small letter lje */, + {0x045a, 0xfa} /* small letter nje */, + {0x045b, 0xfb} /* small letter tshe (serbocroatian) */, + {0x045c, 0xfc} /* small letter kje (macedonian) */, + {0x045e, 0xfe} /* small letter short u (byelorussian) */, + {0x045f, 0xff} /* small letter dzhe */, + {0x2116, 0xf0} /* sign */ +}; + +/* +#define cet_ucs4_to_iso_8859_5_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_5_extra[cet_ucs4_to_iso_8859_5_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_5 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_5, /* name of character set */ + cet_cs_alias_iso_8859_5, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_5, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_5, /* first non standard character */ + cet_ucs4_cnt_iso_8859_5, /* number of values in table */ + + cet_ucs4_to_iso_8859_5_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_5_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_5_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f +}; +*/ + +#endif diff --git a/cet/iso_8859_6.h b/cet/iso_8859_6.h new file mode 100644 index 000000000..dbd7730c4 --- /dev/null +++ b/cet/iso_8859_6.h @@ -0,0 +1,173 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-6" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_6_h +#define iso_8859_6_h + +#define cet_cs_name_iso_8859_6 "ISO-8859-6" + +const char *cet_cs_alias_iso_8859_6[] = +{ + "ISO-8859-6", "arabic", "ASMO-708", "csISOLatinArabic", + "ECMA-114", "ISO8859-6", "iso-ir-127", "ISO_8859-6", + "ISO_8859-6:1987", NULL +}; + +#define cet_ucs4_ofs_iso_8859_6 161 +#define cet_ucs4_cnt_iso_8859_6 82 + +const int cet_ucs4_map_iso_8859_6[cet_ucs4_cnt_iso_8859_6] = +{ + -1, -1, -1, 0x00a4, -1, -1, -1, -1, + -1, -1, -1, 0x060c, 0x00ad, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x061b, -1, -1, -1, 0x061f, -1, + 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, + 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 0x0630, + 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, + 0x0639, 0x063a, -1, -1, -1, -1, -1, 0x0640, + 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, + 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 0x0650, + 0x0651, 0x0652 +}; + +#define cet_ucs4_to_iso_8859_6_ct 48 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_6_links[cet_ucs4_to_iso_8859_6_ct] = +{ + {0x060c, 0xac} /* comma */, + {0x061b, 0xbb} /* semicolon */, + {0x061f, 0xbf} /* question mark */, + {0x0621, 0xc1} /* letter hamza */, + {0x0622, 0xc2} /* letter alef with madda above */, + {0x0623, 0xc3} /* letter alef with hamza above */, + {0x0624, 0xc4} /* letter waw with hamza above */, + {0x0625, 0xc5} /* letter alef with hamza below */, + {0x0626, 0xc6} /* letter yeh with hamza above */, + {0x0627, 0xc7} /* letter alef */, + {0x0628, 0xc8} /* letter beh */, + {0x0629, 0xc9} /* letter teh marbuta */, + {0x062a, 0xca} /* letter teh */, + {0x062b, 0xcb} /* letter theh */, + {0x062c, 0xcc} /* letter jeem */, + {0x062d, 0xcd} /* letter hah */, + {0x062e, 0xce} /* letter khah */, + {0x062f, 0xcf} /* letter dal */, + {0x0630, 0xd0} /* letter thal */, + {0x0631, 0xd1} /* letter reh */, + {0x0632, 0xd2} /* letter zain */, + {0x0633, 0xd3} /* letter seen */, + {0x0634, 0xd4} /* letter sheen */, + {0x0635, 0xd5} /* letter sad */, + {0x0636, 0xd6} /* letter dad */, + {0x0637, 0xd7} /* letter tah */, + {0x0638, 0xd8} /* letter zah */, + {0x0639, 0xd9} /* letter ain */, + {0x063a, 0xda} /* letter ghain */, + {0x0640, 0xe0} /* tatweel */, + {0x0641, 0xe1} /* letter feh */, + {0x0642, 0xe2} /* letter qaf */, + {0x0643, 0xe3} /* letter kaf */, + {0x0644, 0xe4} /* letter lam */, + {0x0645, 0xe5} /* letter meem */, + {0x0646, 0xe6} /* letter noon */, + {0x0647, 0xe7} /* letter heh */, + {0x0648, 0xe8} /* letter waw */, + {0x0649, 0xe9} /* letter alef maksura */, + {0x064a, 0xea} /* letter yeh */, + {0x064b, 0xeb} /* fathatan */, + {0x064c, 0xec} /* dammatan */, + {0x064d, 0xed} /* kasratan */, + {0x064e, 0xee} /* fatha */, + {0x064f, 0xef} /* damma */, + {0x0650, 0xf0} /* kasra */, + {0x0651, 0xf1} /* shadda */, + {0x0652, 0xf2} /* sukun */ +}; + +/* +#define cet_ucs4_to_iso_8859_6_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_6_extra[cet_ucs4_to_iso_8859_6_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_6 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_6, /* name of character set */ + cet_cs_alias_iso_8859_6, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_6, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_6, /* first non standard character */ + cet_ucs4_cnt_iso_8859_6, /* number of values in table */ + + cet_ucs4_to_iso_8859_6_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_6_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_6_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, -1, -1, 0x00a4, -1, -1, -1, + -1, -1, -1, -1, 0x060c, 0x00ad, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 0x061b, -1, -1, -1, 0x061f, + -1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063a, -1, -1, -1, -1, -1, + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + 0x0650, 0x0651, 0x0652, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_7.h b/cet/iso_8859_7.h new file mode 100644 index 000000000..09a6f50c7 --- /dev/null +++ b/cet/iso_8859_7.h @@ -0,0 +1,199 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-7" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_7_h +#define iso_8859_7_h + +#define cet_cs_name_iso_8859_7 "ISO-8859-7" + +const char *cet_cs_alias_iso_8859_7[] = +{ + "ISO-8859-7", "csISOLatinGreek", "ECMA-118", "ELOT_928", + "greek", "greek8", "ISO8859-7", "iso-ir-126", + "ISO_8859-7", "ISO_8859-7:1987", NULL +}; + +#define cet_ucs4_ofs_iso_8859_7 161 +#define cet_ucs4_cnt_iso_8859_7 94 + +const int cet_ucs4_map_iso_8859_7[cet_ucs4_cnt_iso_8859_7] = +{ + 0x201b, 0x2019, 0x00a3, -1, -1, 0x00a6, 0x00a7, 0x00a8, + 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, -1, 0x2014, 0x00b0, + 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x0385, 0x0386, 0x00b7, 0x0388, + 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, 0x0390, + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, + 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03b0, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, + 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce +}; + +#define cet_ucs4_to_iso_8859_7_ct 73 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_7_links[cet_ucs4_to_iso_8859_7_ct] = +{ + {0x0385, 0xb5} /* accent and diaeresis (tonos and dialytika) */, + {0x0386, 0xb6} /* capital letter alpha with acute */, + {0x0388, 0xb8} /* capital letter epsilon with acute */, + {0x0389, 0xb9} /* capital letter eta with acute */, + {0x038a, 0xba} /* capital letter iota with acute */, + {0x038c, 0xbc} /* capital letter omicron with acute */, + {0x038e, 0xbe} /* capital letter upsilon with acute */, + {0x038f, 0xbf} /* capital letter omega with acute */, + {0x0390, 0xc0} /* small letter iota with acute and diaeresis */, + {0x0391, 0xc1} /* capital letter alpha */, + {0x0392, 0xc2} /* capital letter beta */, + {0x0393, 0xc3} /* capital letter gamma */, + {0x0394, 0xc4} /* capital letter delta */, + {0x0395, 0xc5} /* capital letter epsilon */, + {0x0396, 0xc6} /* capital letter zeta */, + {0x0397, 0xc7} /* capital letter eta */, + {0x0398, 0xc8} /* capital letter theta */, + {0x0399, 0xc9} /* capital letter iota */, + {0x039a, 0xca} /* capital letter kappa */, + {0x039b, 0xcb} /* capital letter lamda */, + {0x039c, 0xcc} /* capital letter mu */, + {0x039d, 0xcd} /* capital letter nu */, + {0x039e, 0xce} /* capital letter xi */, + {0x039f, 0xcf} /* capital letter omicron */, + {0x03a0, 0xd0} /* capital letter pi */, + {0x03a1, 0xd1} /* capital letter rho */, + {0x03a3, 0xd3} /* capital letter sigma */, + {0x03a4, 0xd4} /* capital letter tau */, + {0x03a5, 0xd5} /* capital letter upsilon */, + {0x03a6, 0xd6} /* capital letter phi */, + {0x03a7, 0xd7} /* capital letter chi */, + {0x03a8, 0xd8} /* capital letter psi */, + {0x03a9, 0xd9} /* capital letter omega */, + {0x03aa, 0xda} /* capital letter iota with diaeresis */, + {0x03ab, 0xdb} /* capital letter upsilon with diaeresis */, + {0x03ac, 0xdc} /* small letter alpha with acute */, + {0x03ad, 0xdd} /* small letter epsilon with acute */, + {0x03ae, 0xde} /* small letter eta with acute */, + {0x03af, 0xdf} /* small letter iota with acute */, + {0x03b0, 0xe0} /* small letter upsilon with acute and diaeresis */, + {0x03b1, 0xe1} /* small letter alpha */, + {0x03b2, 0xe2} /* small letter beta */, + {0x03b3, 0xe3} /* small letter gamma */, + {0x03b4, 0xe4} /* small letter delta */, + {0x03b5, 0xe5} /* small letter epsilon */, + {0x03b6, 0xe6} /* small letter zeta */, + {0x03b7, 0xe7} /* small letter eta */, + {0x03b8, 0xe8} /* small letter theta */, + {0x03b9, 0xe9} /* small letter iota */, + {0x03ba, 0xea} /* small letter kappa */, + {0x03bb, 0xeb} /* small letter lamda */, + {0x03bc, 0xec} /* small letter mu */, + {0x03bd, 0xed} /* small letter nu */, + {0x03be, 0xee} /* small letter xi */, + {0x03bf, 0xef} /* small letter omicron */, + {0x03c0, 0xf0} /* small letter pi */, + {0x03c1, 0xf1} /* small letter rho */, + {0x03c2, 0xf2} /* small letter final sigma */, + {0x03c3, 0xf3} /* small letter sigma */, + {0x03c4, 0xf4} /* small letter tau */, + {0x03c5, 0xf5} /* small letter upsilon */, + {0x03c6, 0xf6} /* small letter phi */, + {0x03c7, 0xf7} /* small letter chi */, + {0x03c8, 0xf8} /* small letter psi */, + {0x03c9, 0xf9} /* small letter omega */, + {0x03ca, 0xfa} /* small letter iota with diaeresis */, + {0x03cb, 0xfb} /* small letter upsilon with diaeresis */, + {0x03cc, 0xfc} /* small letter omicron with acute */, + {0x03cd, 0xfd} /* small letter upsilon with acute */, + {0x03ce, 0xfe} /* small letter omega with acute */, + {0x2014, 0xaf} /* dash */, + {0x2019, 0xa2} /* single quotation mark */, + {0x201b, 0xa1} /* high-reversed-9 quotation mark */ +}; + +/* +#define cet_ucs4_to_iso_8859_7_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_7_extra[cet_ucs4_to_iso_8859_7_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_7 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_7, /* name of character set */ + cet_cs_alias_iso_8859_7, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_7, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_7, /* first non standard character */ + cet_ucs4_cnt_iso_8859_7, /* number of values in table */ + + cet_ucs4_to_iso_8859_7_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_7_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_7_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x201b, 0x2019, 0x00a3, -1, -1, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, -1, 0x00ab, 0x00ac, 0x00ad, -1, 0x2014, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x0385, 0x0386, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + 0x03a0, 0x03a1, -1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_8.h b/cet/iso_8859_8.h new file mode 100644 index 000000000..e22f04a60 --- /dev/null +++ b/cet/iso_8859_8.h @@ -0,0 +1,156 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-8" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_8_h +#define iso_8859_8_h + +#define cet_cs_name_iso_8859_8 "ISO-8859-8" + +const char *cet_cs_alias_iso_8859_8[] = +{ + "ISO-8859-8", "csISOLatinHebrew", "hebrew", "ISO8859-8", + "iso-ir-138", "ISO_8859-8", "ISO_8859-8:1988", NULL +}; + +#define cet_ucs4_ofs_iso_8859_8 161 +#define cet_ucs4_cnt_iso_8859_8 90 + +const int cet_ucs4_map_iso_8859_8[cet_ucs4_cnt_iso_8859_8] = +{ + -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, + 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, 0x00b0, + 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, + 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0x2017, 0x05d0, + 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, + 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 0x05e0, + 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, + 0x05e9, 0x05ea +}; + +#define cet_ucs4_to_iso_8859_8_ct 31 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_8_links[cet_ucs4_to_iso_8859_8_ct] = +{ + {0x00d7, 0xaa} /* sign */, + {0x00f7, 0xba} /* sign */, + {0x05d0, 0xe0} /* letter alef */, + {0x05d1, 0xe1} /* letter bet */, + {0x05d2, 0xe2} /* letter gimel */, + {0x05d3, 0xe3} /* letter dalet */, + {0x05d4, 0xe4} /* letter he */, + {0x05d5, 0xe5} /* letter vav */, + {0x05d6, 0xe6} /* letter zayin */, + {0x05d7, 0xe7} /* letter het */, + {0x05d8, 0xe8} /* letter tet */, + {0x05d9, 0xe9} /* letter yod */, + {0x05da, 0xea} /* letter final kaf */, + {0x05db, 0xeb} /* letter kaf */, + {0x05dc, 0xec} /* letter lamed */, + {0x05dd, 0xed} /* letter final mem */, + {0x05de, 0xee} /* letter mem */, + {0x05df, 0xef} /* letter final nun */, + {0x05e0, 0xf0} /* letter nun */, + {0x05e1, 0xf1} /* letter samekh */, + {0x05e2, 0xf2} /* letter ayin */, + {0x05e3, 0xf3} /* letter final pe */, + {0x05e4, 0xf4} /* letter pe */, + {0x05e5, 0xf5} /* letter final tsadi */, + {0x05e6, 0xf6} /* letter tsadi */, + {0x05e7, 0xf7} /* letter qof */, + {0x05e8, 0xf8} /* letter resh */, + {0x05e9, 0xf9} /* letter shin */, + {0x05ea, 0xfa} /* letter tav */, + {0x2017, 0xdf} /* low line */, + {0x203e, 0xaf} /* overline */ +}; + +/* +#define cet_ucs4_to_iso_8859_8_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_8_extra[cet_ucs4_to_iso_8859_8_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_8 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_8, /* name of character set */ + cet_cs_alias_iso_8859_8, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_8, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_8, /* first non standard character */ + cet_ucs4_cnt_iso_8859_8, /* number of values in table */ + + cet_ucs4_to_iso_8859_8_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_8_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_8_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0x2017, + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/iso_8859_9.h b/cet/iso_8859_9.h new file mode 100644 index 000000000..4babb270b --- /dev/null +++ b/cet/iso_8859_9.h @@ -0,0 +1,129 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO-8859-9" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_9_h +#define iso_8859_9_h + +#define cet_cs_name_iso_8859_9 "ISO-8859-9" + +const char *cet_cs_alias_iso_8859_9[] = +{ + "ISO-8859-9", "csISOLatin5", "ISO8859-9", "iso-ir-148", + "ISO_8859-9", "ISO_8859-9:1989", "l5", "lat5", "latin5", + NULL +}; + +#define cet_ucs4_ofs_iso_8859_9 208 +#define cet_ucs4_cnt_iso_8859_9 48 + +const int cet_ucs4_map_iso_8859_9[cet_ucs4_cnt_iso_8859_9] = +{ + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; + +#define cet_ucs4_to_iso_8859_9_ct 9 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_9_links[cet_ucs4_to_iso_8859_9_ct] = +{ + {0x0117, 0xec} /* small letter e with dot above */, + {0x0119, 0xea} /* small letter e with ogonek */, + {0x011e, 0xd0} /* capital letter g with breve */, + {0x011f, 0xf0} /* small letter g with breve */, + {0x012b, 0xef} /* small letter i with macron */, + {0x0130, 0xdd} /* capital letter i with dot above */, + {0x0131, 0xfd} /* small letter i dotless */, + {0x015e, 0xde} /* capital letter s with cedilla */, + {0x015f, 0xfe} /* small letter s with cedilla */ +}; + +/* +#define cet_ucs4_to_iso_8859_9_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_9_extra[cet_ucs4_to_iso_8859_9_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_9 = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_9, /* name of character set */ + cet_cs_alias_iso_8859_9, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_9, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_9, /* first non standard character */ + cet_ucs4_cnt_iso_8859_9, /* number of values in table */ + + cet_ucs4_to_iso_8859_9_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_9_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_9_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff +}; +*/ + +#endif diff --git a/cet/iso_8859_supp.h b/cet/iso_8859_supp.h new file mode 100644 index 000000000..1c7f05724 --- /dev/null +++ b/cet/iso_8859_supp.h @@ -0,0 +1,212 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "ISO_8859-supp" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef iso_8859_supp_h +#define iso_8859_supp_h + +#define cet_cs_name_iso_8859_supp "ISO_8859-supp" + +const char *cet_cs_alias_iso_8859_supp[] = +{ + "ISO_8859-supp", "iso-ir-154", "latin1-2-5", NULL +}; + +#define cet_ucs4_ofs_iso_8859_supp 160 +#define cet_ucs4_cnt_iso_8859_supp 96 + +const int cet_ucs4_map_iso_8859_supp[cet_ucs4_cnt_iso_8859_supp] = +{ + -1, -1, 0x0100, 0x0108, 0x010a, -1, 0x0116, 0x0112, + 0x011c, 0x2018, 0x201c, 0x2122, 0x2190, 0x2191, 0x2192, 0x2193, + -1, -1, 0x0101, 0x0109, 0x010b, 0x00f0, 0x0117, 0x0113, + 0x011d, 0x2019, 0x201d, 0x266a, 0x215b, 0x215c, 0x215d, 0x215e, + -1, 0x011e, 0x0120, 0x0122, 0x0124, 0x0126, 0x0128, 0x0130, + 0x012a, 0x012e, 0x0132, 0x0134, 0x0136, 0x013b, 0x013f, 0x0145, + 0x2014, 0x014a, 0x014c, 0x0152, 0x0156, 0x015c, 0x0166, 0x00de, + 0x0168, 0x016c, 0x016a, 0x0172, 0x0174, 0x00dd, 0x0176, 0x0178, + 0x2126, 0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x0131, + 0x012b, 0x012f, 0x0133, 0x0135, 0x0137, 0x013c, 0x0140, 0x0146, + 0x0138, 0x014b, 0x014d, 0x0153, 0x0157, 0x015d, 0x0167, 0x00fe, + 0x0169, 0x016d, 0x016b, 0x0173, 0x0175, 0x00fd, 0x0177, 0x0149 +}; + +#define cet_ucs4_to_iso_8859_supp_ct 88 + +const cet_ucs4_link_t cet_ucs4_to_iso_8859_supp_links[cet_ucs4_to_iso_8859_supp_ct] = +{ + {0x00de, 0xd7} /* capital letter thorn (icelandic) */, + {0x00f0, 0xb5} /* small letter eth (icelandic) */, + {0x00fe, 0xf7} /* small letter thorn (icelandic) */, + {0x0100, 0xa2} /* capital letter a with macron */, + {0x0101, 0xb2} /* small letter a with macron */, + {0x0108, 0xa3} /* capital letter c with circumflex */, + {0x0109, 0xb3} /* small letter c with circumflex */, + {0x010a, 0xa4} /* capital letter c with dot above */, + {0x010b, 0xb4} /* small letter c with dot above */, + {0x0112, 0xa7} /* capital letter e with macron */, + {0x0113, 0xb7} /* small letter e with macron */, + {0x0116, 0xa6} /* capital letter e with dot above */, + {0x0117, 0xb6} /* small letter e with dot above */, + {0x011c, 0xa8} /* capital letter g with circumflex */, + {0x011d, 0xb8} /* small letter g with circumflex */, + {0x011e, 0xc1} /* capital letter g with breve */, + {0x011f, 0xe1} /* small letter g with breve */, + {0x0120, 0xc2} /* capital letter g with dot above */, + {0x0121, 0xe2} /* small letter g with dot above */, + {0x0122, 0xc3} /* capital letter g with cedilla */, + {0x0123, 0xe3} /* small letter g with cedilla */, + {0x0124, 0xc4} /* capital letter h with circumflex */, + {0x0125, 0xe4} /* small letter h with circumflex */, + {0x0126, 0xc5} /* capital letter h with stroke */, + {0x0127, 0xe5} /* small letter h with stroke */, + {0x0128, 0xc6} /* capital letter i with tilde */, + {0x0129, 0xe6} /* small letter i with tilde */, + {0x012a, 0xc8} /* capital letter i with macron */, + {0x012b, 0xe8} /* small letter i with macron */, + {0x012e, 0xc9} /* capital letter i with ogonek */, + {0x012f, 0xe9} /* small letter i with ogonek */, + {0x0130, 0xc7} /* capital letter i with dot above */, + {0x0131, 0xe7} /* small letter i dotless */, + {0x0132, 0xca} /* capital ligature ij */, + {0x0133, 0xea} /* small ligature ij */, + {0x0134, 0xcb} /* capital letter j with circumflex */, + {0x0135, 0xeb} /* small letter j with circumflex */, + {0x0136, 0xcc} /* capital letter k with cedilla */, + {0x0137, 0xec} /* small letter k with cedilla */, + {0x0138, 0xf0} /* small letter kra (greenlandic) */, + {0x013b, 0xcd} /* capital letter l with cedilla */, + {0x013c, 0xed} /* small letter l with cedilla */, + {0x013f, 0xce} /* capital letter l with middle dot */, + {0x0140, 0xee} /* small letter l with middle dot */, + {0x0145, 0xcf} /* capital letter n with cedilla */, + {0x0146, 0xef} /* small letter n with cedilla */, + {0x0149, 0xff} /* small letter n preceded by apostrophe */, + {0x014a, 0xd1} /* capital letter eng (lappish) */, + {0x014b, 0xf1} /* small letter eng (lappish) */, + {0x014c, 0xd2} /* capital letter o with macron */, + {0x014d, 0xf2} /* small letter o with macron */, + {0x0152, 0xd3} /* capital ligature oe */, + {0x0153, 0xf3} /* small ligature oe */, + {0x0156, 0xd4} /* capital letter r with cedilla */, + {0x0157, 0xf4} /* small letter r with cedilla */, + {0x015c, 0xd5} /* capital letter s with circumflex */, + {0x015d, 0xf5} /* small letter s with circumflex */, + {0x0166, 0xd6} /* capital letter t with stroke */, + {0x0167, 0xf6} /* small letter t with stroke */, + {0x0168, 0xd8} /* capital letter u with tilde */, + {0x0169, 0xf8} /* small letter u with tilde */, + {0x016a, 0xda} /* capital letter u with macron */, + {0x016b, 0xfa} /* small letter u with macron */, + {0x016c, 0xd9} /* capital letter u with breve */, + {0x016d, 0xf9} /* small letter u with breve */, + {0x0172, 0xdb} /* capital letter u with ogonek */, + {0x0173, 0xfb} /* small letter u with ogonek */, + {0x0174, 0xdc} /* capital letter w with circumflex */, + {0x0175, 0xfc} /* small letter w with circumflex */, + {0x0176, 0xde} /* capital letter y with circumflex */, + {0x0177, 0xfe} /* small letter y with circumflex */, + {0x0178, 0xdf} /* capital letter y with diaeresis */, + {0x2014, 0xd0} /* dash */, + {0x2018, 0xa9} /* single quotation mark */, + {0x2019, 0xb9} /* single quotation mark */, + {0x201c, 0xaa} /* double quotation mark */, + {0x201d, 0xba} /* double quotation mark */, + {0x2122, 0xab} /* mark sign */, + {0x2126, 0xe0} /* sign */, + {0x215b, 0xbc} /* fraction one eighth */, + {0x215c, 0xbd} /* fraction three eighths */, + {0x215d, 0xbe} /* fraction five eighths */, + {0x215e, 0xbf} /* fraction seven eighths */, + {0x2190, 0xac} /* arrow */, + {0x2191, 0xad} /* arrow */, + {0x2192, 0xae} /* arrow */, + {0x2193, 0xaf} /* arrow */, + {0x266a, 0xbb} /* note */ +}; + +/* +#define cet_ucs4_to_iso_8859_supp_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_iso_8859_supp_extra[cet_ucs4_to_iso_8859_supp_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_iso_8859_supp = /* defined in cet.h */ +{ + cet_cs_name_iso_8859_supp, /* name of character set */ + cet_cs_alias_iso_8859_supp, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_iso_8859_supp, /* char to UCS-4 value table */ + cet_ucs4_ofs_iso_8859_supp, /* first non standard character */ + cet_ucs4_cnt_iso_8859_supp, /* number of values in table */ + + cet_ucs4_to_iso_8859_supp_links, /* UCS-4 to char links */ + cet_ucs4_to_iso_8859_supp_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int iso_8859_supp_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, -1, 0x0100, 0x0108, 0x010a, -1, 0x0116, 0x0112, + 0x011c, 0x2018, 0x201c, 0x2122, 0x2190, 0x2191, 0x2192, 0x2193, + -1, -1, 0x0101, 0x0109, 0x010b, 0x00f0, 0x0117, 0x0113, + 0x011d, 0x2019, 0x201d, 0x266a, 0x215b, 0x215c, 0x215d, 0x215e, + -1, 0x011e, 0x0120, 0x0122, 0x0124, 0x0126, 0x0128, 0x0130, + 0x012a, 0x012e, 0x0132, 0x0134, 0x0136, 0x013b, 0x013f, 0x0145, + 0x2014, 0x014a, 0x014c, 0x0152, 0x0156, 0x015c, 0x0166, 0x00de, + 0x0168, 0x016c, 0x016a, 0x0172, 0x0174, 0x00dd, 0x0176, 0x0178, + 0x2126, 0x011f, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0x0131, + 0x012b, 0x012f, 0x0133, 0x0135, 0x0137, 0x013c, 0x0140, 0x0146, + 0x0138, 0x014b, 0x014d, 0x0153, 0x0157, 0x015d, 0x0167, 0x00fe, + 0x0169, 0x016d, 0x016b, 0x0173, 0x0175, 0x00fd, 0x0177, 0x0149 +}; +*/ + +#endif diff --git a/cet/it.h b/cet/it.h new file mode 100644 index 000000000..178d100bf --- /dev/null +++ b/cet/it.h @@ -0,0 +1,134 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "IT" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef it_h +#define it_h + +#define cet_cs_name_it "IT" + +const char *cet_cs_alias_it[] = +{ + "IT", "ISO646-IT", "iso-ir-15", NULL +}; + +#define cet_ucs4_ofs_it 35 +#define cet_ucs4_cnt_it 93 + +const int cet_ucs4_map_it[cet_ucs4_cnt_it] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00a7, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00b0, 0x00e7, 0x00e9, 0x005e, 0x005f, 0x00f9, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e0, 0x00f2, 0x00e8, 0x00ec, 0x007f +}; + +#define cet_ucs4_to_it_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_it_links[cet_ucs4_to_it_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x40} /* sign */, + {0x00b0, 0x5b} /* sign */, + {0x00e0, 0x7b} /* small letter a with grave */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x5d} /* small letter e with acute */, + {0x00ec, 0x7e} /* small letter i with grave */, + {0x00f2, 0x7c} /* small letter o with grave */, + {0x00f9, 0x60} /* small letter u with grave */ +}; + +/* +#define cet_ucs4_to_it_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_it_extra[cet_ucs4_to_it_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_it = /* defined in cet.h */ +{ + cet_cs_name_it, /* name of character set */ + cet_cs_alias_it, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_it, /* char to UCS-4 value table */ + cet_ucs4_ofs_it, /* first non standard character */ + cet_ucs4_cnt_it, /* number of values in table */ + + cet_ucs4_to_it_links, /* UCS-4 to char links */ + cet_ucs4_to_it_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int it_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00e9, 0x005e, 0x005f, + 0x00f9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e0, 0x00f2, 0x00e8, 0x00ec, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jis_c6220_1969_ro.h b/cet/jis_c6220_1969_ro.h new file mode 100644 index 000000000..2227d0fcf --- /dev/null +++ b/cet/jis_c6220_1969_ro.h @@ -0,0 +1,120 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JIS_C6220-1969-ro" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jis_c6220_1969_ro_h +#define jis_c6220_1969_ro_h + +#define cet_cs_name_jis_c6220_1969_ro "JIS_C6220-1969-ro" + +const char *cet_cs_alias_jis_c6220_1969_ro[] = +{ + "JIS_C6220-1969-ro", "csISO14JISC6220ro", "ISO646-JP", "iso-ir-14", + "jp", NULL +}; + +#define cet_ucs4_ofs_jis_c6220_1969_ro 92 +#define cet_ucs4_cnt_jis_c6220_1969_ro 36 + +const int cet_ucs4_map_jis_c6220_1969_ro[cet_ucs4_cnt_jis_c6220_1969_ro] = +{ + 0x00a5, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_jis_c6220_1969_ro_ct 2 + +const cet_ucs4_link_t cet_ucs4_to_jis_c6220_1969_ro_links[cet_ucs4_to_jis_c6220_1969_ro_ct] = +{ + {0x00a5, 0x5c} /* sign */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_jis_c6220_1969_ro_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jis_c6220_1969_ro_extra[cet_ucs4_to_jis_c6220_1969_ro_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jis_c6220_1969_ro = /* defined in cet.h */ +{ + cet_cs_name_jis_c6220_1969_ro, /* name of character set */ + cet_cs_alias_jis_c6220_1969_ro, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jis_c6220_1969_ro, /* char to UCS-4 value table */ + cet_ucs4_ofs_jis_c6220_1969_ro, /* first non standard character */ + cet_ucs4_cnt_jis_c6220_1969_ro, /* number of values in table */ + + cet_ucs4_to_jis_c6220_1969_ro_links, /* UCS-4 to char links */ + cet_ucs4_to_jis_c6220_1969_ro_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jis_c6220_1969_ro_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jis_x0201.h b/cet/jis_x0201.h new file mode 100644 index 000000000..0675cb3ac --- /dev/null +++ b/cet/jis_x0201.h @@ -0,0 +1,195 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JIS_X0201" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jis_x0201_h +#define jis_x0201_h + +#define cet_cs_name_jis_x0201 "JIS_X0201" + +const char *cet_cs_alias_jis_x0201[] = +{ + "JIS_X0201", "csHalfWidthKatakana", "JIS0201", "JISX0201-1976", + "JISX0201.1976-0", "X0201", NULL +}; + +#define cet_ucs4_ofs_jis_x0201 92 +#define cet_ucs4_cnt_jis_x0201 132 + +const int cet_ucs4_map_jis_x0201[cet_ucs4_cnt_jis_x0201] = +{ + 0x00a5, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x203e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, -1, 0x3002, 0x300c, 0x300d, + 0x3001, 0x30fb, 0x30f2, 0x30a1, 0x30a3, 0x30a5, 0x30a7, 0x30a9, + 0x30e3, 0x30e5, 0x30e7, 0x30c3, 0x30fc, 0x30a2, 0x30a4, 0x30a6, + 0x30a8, 0x30aa, 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, + 0x30b7, 0x30b9, 0x30bb, 0x30bd, 0x30bf, 0x30c1, 0x30c4, 0x30c6, + 0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d2, + 0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2, + 0x30e4, 0x30e6, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, + 0x30ef, 0x30f3, 0x309b, 0x309c +}; + +#define cet_ucs4_to_jis_x0201_ct 65 + +const cet_ucs4_link_t cet_ucs4_to_jis_x0201_links[cet_ucs4_to_jis_x0201_ct] = +{ + {0x00a5, 0x5c} /* sign */, + {0x203e, 0x7e} /* overline */, + {0x3001, 0xa4} /* comma */, + {0x3002, 0xa1} /* period */, + {0x300c, 0xa2} /* corner bracket */, + {0x300d, 0xa3} /* corner bracket */, + {0x309b, 0xde} /* voiced sound mark */, + {0x309c, 0xdf} /* semi-voiced sound mark */, + {0x30a1, 0xa7} /* letter small a */, + {0x30a2, 0xb1} /* letter a */, + {0x30a3, 0xa8} /* letter small i */, + {0x30a4, 0xb2} /* letter i */, + {0x30a5, 0xa9} /* letter small u */, + {0x30a6, 0xb3} /* letter u */, + {0x30a7, 0xaa} /* letter small e */, + {0x30a8, 0xb4} /* letter e */, + {0x30a9, 0xab} /* letter small o */, + {0x30aa, 0xb5} /* letter o */, + {0x30ab, 0xb6} /* letter ka */, + {0x30ad, 0xb7} /* letter ki */, + {0x30af, 0xb8} /* letter ku */, + {0x30b1, 0xb9} /* letter ke */, + {0x30b3, 0xba} /* letter ko */, + {0x30b5, 0xbb} /* letter sa */, + {0x30b7, 0xbc} /* letter si */, + {0x30b9, 0xbd} /* letter su */, + {0x30bb, 0xbe} /* letter se */, + {0x30bd, 0xbf} /* letter so */, + {0x30bf, 0xc0} /* letter ta */, + {0x30c1, 0xc1} /* letter ti */, + {0x30c3, 0xaf} /* letter small tu */, + {0x30c4, 0xc2} /* letter tu */, + {0x30c6, 0xc3} /* letter te */, + {0x30c8, 0xc4} /* letter to */, + {0x30ca, 0xc5} /* letter na */, + {0x30cb, 0xc6} /* letter ni */, + {0x30cc, 0xc7} /* letter nu */, + {0x30cd, 0xc8} /* letter ne */, + {0x30ce, 0xc9} /* letter no */, + {0x30cf, 0xca} /* letter ha */, + {0x30d2, 0xcb} /* letter hi */, + {0x30d5, 0xcc} /* letter hu */, + {0x30d8, 0xcd} /* letter he */, + {0x30db, 0xce} /* letter ho */, + {0x30de, 0xcf} /* letter ma */, + {0x30df, 0xd0} /* letter mi */, + {0x30e0, 0xd1} /* letter mu */, + {0x30e1, 0xd2} /* letter me */, + {0x30e2, 0xd3} /* letter mo */, + {0x30e3, 0xac} /* letter small ya */, + {0x30e4, 0xd4} /* letter ya */, + {0x30e5, 0xad} /* letter small yu */, + {0x30e6, 0xd5} /* letter yu */, + {0x30e7, 0xae} /* letter small yo */, + {0x30e8, 0xd6} /* letter yo */, + {0x30e9, 0xd7} /* letter ra */, + {0x30ea, 0xd8} /* letter ri */, + {0x30eb, 0xd9} /* letter ru */, + {0x30ec, 0xda} /* letter re */, + {0x30ed, 0xdb} /* letter ro */, + {0x30ef, 0xdc} /* letter wa */, + {0x30f2, 0xa6} /* letter wo */, + {0x30f3, 0xdd} /* letter n */, + {0x30fb, 0xa5} /* middle dot */, + {0x30fc, 0xb0} /* prolonged sound mark */ +}; + +/* +#define cet_ucs4_to_jis_x0201_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jis_x0201_extra[cet_ucs4_to_jis_x0201_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jis_x0201 = /* defined in cet.h */ +{ + cet_cs_name_jis_x0201, /* name of character set */ + cet_cs_alias_jis_x0201, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jis_x0201, /* char to UCS-4 value table */ + cet_ucs4_ofs_jis_x0201, /* first non standard character */ + cet_ucs4_cnt_jis_x0201, /* number of values in table */ + + cet_ucs4_to_jis_x0201_links, /* UCS-4 to char links */ + cet_ucs4_to_jis_x0201_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jis_x0201_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + -1, 0x3002, 0x300c, 0x300d, 0x3001, 0x30fb, 0x30f2, 0x30a1, + 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, + 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, + 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, + 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, + 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, + 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, + 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jus_i_b1_002.h b/cet/jus_i_b1_002.h new file mode 100644 index 000000000..fc8c7e936 --- /dev/null +++ b/cet/jus_i_b1_002.h @@ -0,0 +1,131 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JUS_I.B1.002" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jus_i_b1_002_h +#define jus_i_b1_002_h + +#define cet_cs_name_jus_i_b1_002 "JUS_I.B1.002" + +const char *cet_cs_alias_jus_i_b1_002[] = +{ + "JUS_I.B1.002", "ISO646-YU", "iso-ir-141", "js", + "yu", NULL +}; + +#define cet_ucs4_ofs_jus_i_b1_002 64 +#define cet_ucs4_cnt_jus_i_b1_002 64 + +const int cet_ucs4_map_jus_i_b1_002[cet_ucs4_cnt_jus_i_b1_002] = +{ + 0x017d, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x0160, 0x0110, 0x0106, 0x010c, 0x005f, + 0x017e, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x0161, 0x0111, 0x0107, 0x010d, 0x007f +}; + +#define cet_ucs4_to_jus_i_b1_002_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_002_links[cet_ucs4_to_jus_i_b1_002_ct] = +{ + {0x0106, 0x5d} /* capital letter c with acute */, + {0x0107, 0x7d} /* small letter c with acute */, + {0x010c, 0x5e} /* capital letter c with caron */, + {0x010d, 0x7e} /* small letter c with caron */, + {0x0110, 0x5c} /* capital letter d with stroke */, + {0x0111, 0x7c} /* small letter d with stroke */, + {0x0160, 0x5b} /* capital letter s with caron */, + {0x0161, 0x7b} /* small letter s with caron */, + {0x017d, 0x40} /* capital letter z with caron */, + {0x017e, 0x60} /* small letter z with caron */ +}; + +/* +#define cet_ucs4_to_jus_i_b1_002_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_002_extra[cet_ucs4_to_jus_i_b1_002_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jus_i_b1_002 = /* defined in cet.h */ +{ + cet_cs_name_jus_i_b1_002, /* name of character set */ + cet_cs_alias_jus_i_b1_002, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jus_i_b1_002, /* char to UCS-4 value table */ + cet_ucs4_ofs_jus_i_b1_002, /* first non standard character */ + cet_ucs4_cnt_jus_i_b1_002, /* number of values in table */ + + cet_ucs4_to_jus_i_b1_002_links, /* UCS-4 to char links */ + cet_ucs4_to_jus_i_b1_002_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jus_i_b1_002_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x017d, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x0160, 0x0110, 0x0106, 0x010c, 0x005f, + 0x017e, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x0161, 0x0111, 0x0107, 0x010d, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jus_i_b1_003_mac.h b/cet/jus_i_b1_003_mac.h new file mode 100644 index 000000000..7082a0d43 --- /dev/null +++ b/cet/jus_i_b1_003_mac.h @@ -0,0 +1,182 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JUS_I.B1.003-mac" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jus_i_b1_003_mac_h +#define jus_i_b1_003_mac_h + +#define cet_cs_name_jus_i_b1_003_mac "JUS_I.B1.003-mac" + +const char *cet_cs_alias_jus_i_b1_003_mac[] = +{ + "JUS_I.B1.003-mac", "iso-ir-147", "macedonian", NULL +}; + +#define cet_ucs4_ofs_jus_i_b1_003_mac 64 +#define cet_ucs4_cnt_jus_i_b1_003_mac 64 + +const int cet_ucs4_map_jus_i_b1_003_mac[cet_ucs4_cnt_jus_i_b1_003_mac] = +{ + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0403, 0x040c, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0453, 0x045c, 0x0447, 0x007f +}; + +#define cet_ucs4_to_jus_i_b1_003_mac_ct 62 + +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_mac_links[cet_ucs4_to_jus_i_b1_003_mac_ct] = +{ + {0x0403, 0x5c} /* capital letter gje (macedonian) */, + {0x0405, 0x59} /* capital letter dze (macedonian) */, + {0x0408, 0x4a} /* capital letter je */, + {0x0409, 0x51} /* capital letter lje */, + {0x040a, 0x57} /* capital letter nje */, + {0x040c, 0x5d} /* capital letter kje (macedonian) */, + {0x040f, 0x58} /* capital letter dzhe */, + {0x0410, 0x41} /* capital letter a */, + {0x0411, 0x42} /* capital letter be */, + {0x0412, 0x56} /* capital letter ve */, + {0x0413, 0x47} /* capital letter ghe */, + {0x0414, 0x44} /* capital letter de */, + {0x0415, 0x45} /* capital letter ie */, + {0x0416, 0x40} /* capital letter zhe */, + {0x0417, 0x5a} /* capital letter ze */, + {0x0418, 0x49} /* capital letter i */, + {0x041a, 0x4b} /* capital letter ka */, + {0x041b, 0x4c} /* capital letter el */, + {0x041c, 0x4d} /* capital letter em */, + {0x041d, 0x4e} /* capital letter en */, + {0x041e, 0x4f} /* capital letter o */, + {0x041f, 0x50} /* capital letter pe */, + {0x0420, 0x52} /* capital letter er */, + {0x0421, 0x53} /* capital letter es */, + {0x0422, 0x54} /* capital letter te */, + {0x0423, 0x55} /* capital letter u */, + {0x0424, 0x46} /* capital letter ef */, + {0x0425, 0x48} /* capital letter ha */, + {0x0426, 0x43} /* capital letter tse */, + {0x0427, 0x5e} /* capital letter che */, + {0x0428, 0x5b} /* capital letter sha */, + {0x0430, 0x61} /* small letter a */, + {0x0431, 0x62} /* small letter be */, + {0x0432, 0x76} /* small letter ve */, + {0x0433, 0x67} /* small letter ghe */, + {0x0434, 0x64} /* small letter de */, + {0x0435, 0x65} /* small letter ie */, + {0x0436, 0x60} /* small letter zhe */, + {0x0437, 0x7a} /* small letter ze */, + {0x0438, 0x69} /* small letter i */, + {0x043a, 0x6b} /* small letter ka */, + {0x043b, 0x6c} /* small letter el */, + {0x043c, 0x6d} /* small letter em */, + {0x043d, 0x6e} /* small letter en */, + {0x043e, 0x6f} /* small letter o */, + {0x043f, 0x70} /* small letter pe */, + {0x0440, 0x72} /* small letter er */, + {0x0441, 0x73} /* small letter es */, + {0x0442, 0x74} /* small letter te */, + {0x0443, 0x75} /* small letter u */, + {0x0444, 0x66} /* small letter ef */, + {0x0445, 0x68} /* small letter ha */, + {0x0446, 0x63} /* small letter tse */, + {0x0447, 0x7e} /* small letter che */, + {0x0448, 0x7b} /* small letter sha */, + {0x0453, 0x7c} /* small letter gje (macedonian) */, + {0x0455, 0x79} /* small letter dze (macedonian) */, + {0x0458, 0x6a} /* small letter je */, + {0x0459, 0x71} /* small letter lje */, + {0x045a, 0x77} /* small letter nje */, + {0x045c, 0x7d} /* small letter kje (macedonian) */, + {0x045f, 0x78} /* small letter dzhe */ +}; + +/* +#define cet_ucs4_to_jus_i_b1_003_mac_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_mac_extra[cet_ucs4_to_jus_i_b1_003_mac_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jus_i_b1_003_mac = /* defined in cet.h */ +{ + cet_cs_name_jus_i_b1_003_mac, /* name of character set */ + cet_cs_alias_jus_i_b1_003_mac, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jus_i_b1_003_mac, /* char to UCS-4 value table */ + cet_ucs4_ofs_jus_i_b1_003_mac, /* first non standard character */ + cet_ucs4_cnt_jus_i_b1_003_mac, /* number of values in table */ + + cet_ucs4_to_jus_i_b1_003_mac_links, /* UCS-4 to char links */ + cet_ucs4_to_jus_i_b1_003_mac_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jus_i_b1_003_mac_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0403, 0x040c, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0453, 0x045c, 0x0447, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/jus_i_b1_003_serb.h b/cet/jus_i_b1_003_serb.h new file mode 100644 index 000000000..10b81f1ec --- /dev/null +++ b/cet/jus_i_b1_003_serb.h @@ -0,0 +1,182 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "JUS_I.B1.003-serb" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef jus_i_b1_003_serb_h +#define jus_i_b1_003_serb_h + +#define cet_cs_name_jus_i_b1_003_serb "JUS_I.B1.003-serb" + +const char *cet_cs_alias_jus_i_b1_003_serb[] = +{ + "JUS_I.B1.003-serb", "iso-ir-146", "serbian", NULL +}; + +#define cet_ucs4_ofs_jus_i_b1_003_serb 64 +#define cet_ucs4_cnt_jus_i_b1_003_serb 64 + +const int cet_ucs4_map_jus_i_b1_003_serb[cet_ucs4_cnt_jus_i_b1_003_serb] = +{ + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0402, 0x040b, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0452, 0x045b, 0x0447, 0x007f +}; + +#define cet_ucs4_to_jus_i_b1_003_serb_ct 62 + +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_serb_links[cet_ucs4_to_jus_i_b1_003_serb_ct] = +{ + {0x0402, 0x5c} /* capital letter dje (serbocroatian) */, + {0x0405, 0x59} /* capital letter dze (macedonian) */, + {0x0408, 0x4a} /* capital letter je */, + {0x0409, 0x51} /* capital letter lje */, + {0x040a, 0x57} /* capital letter nje */, + {0x040b, 0x5d} /* capital letter tshe (serbocroatian) */, + {0x040f, 0x58} /* capital letter dzhe */, + {0x0410, 0x41} /* capital letter a */, + {0x0411, 0x42} /* capital letter be */, + {0x0412, 0x56} /* capital letter ve */, + {0x0413, 0x47} /* capital letter ghe */, + {0x0414, 0x44} /* capital letter de */, + {0x0415, 0x45} /* capital letter ie */, + {0x0416, 0x40} /* capital letter zhe */, + {0x0417, 0x5a} /* capital letter ze */, + {0x0418, 0x49} /* capital letter i */, + {0x041a, 0x4b} /* capital letter ka */, + {0x041b, 0x4c} /* capital letter el */, + {0x041c, 0x4d} /* capital letter em */, + {0x041d, 0x4e} /* capital letter en */, + {0x041e, 0x4f} /* capital letter o */, + {0x041f, 0x50} /* capital letter pe */, + {0x0420, 0x52} /* capital letter er */, + {0x0421, 0x53} /* capital letter es */, + {0x0422, 0x54} /* capital letter te */, + {0x0423, 0x55} /* capital letter u */, + {0x0424, 0x46} /* capital letter ef */, + {0x0425, 0x48} /* capital letter ha */, + {0x0426, 0x43} /* capital letter tse */, + {0x0427, 0x5e} /* capital letter che */, + {0x0428, 0x5b} /* capital letter sha */, + {0x0430, 0x61} /* small letter a */, + {0x0431, 0x62} /* small letter be */, + {0x0432, 0x76} /* small letter ve */, + {0x0433, 0x67} /* small letter ghe */, + {0x0434, 0x64} /* small letter de */, + {0x0435, 0x65} /* small letter ie */, + {0x0436, 0x60} /* small letter zhe */, + {0x0437, 0x7a} /* small letter ze */, + {0x0438, 0x69} /* small letter i */, + {0x043a, 0x6b} /* small letter ka */, + {0x043b, 0x6c} /* small letter el */, + {0x043c, 0x6d} /* small letter em */, + {0x043d, 0x6e} /* small letter en */, + {0x043e, 0x6f} /* small letter o */, + {0x043f, 0x70} /* small letter pe */, + {0x0440, 0x72} /* small letter er */, + {0x0441, 0x73} /* small letter es */, + {0x0442, 0x74} /* small letter te */, + {0x0443, 0x75} /* small letter u */, + {0x0444, 0x66} /* small letter ef */, + {0x0445, 0x68} /* small letter ha */, + {0x0446, 0x63} /* small letter tse */, + {0x0447, 0x7e} /* small letter che */, + {0x0448, 0x7b} /* small letter sha */, + {0x0452, 0x7c} /* small letter dje (serbocroatian) */, + {0x0455, 0x79} /* small letter dze (macedonian) */, + {0x0458, 0x6a} /* small letter je */, + {0x0459, 0x71} /* small letter lje */, + {0x045a, 0x77} /* small letter nje */, + {0x045b, 0x7d} /* small letter tshe (serbocroatian) */, + {0x045f, 0x78} /* small letter dzhe */ +}; + +/* +#define cet_ucs4_to_jus_i_b1_003_serb_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_jus_i_b1_003_serb_extra[cet_ucs4_to_jus_i_b1_003_serb_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_jus_i_b1_003_serb = /* defined in cet.h */ +{ + cet_cs_name_jus_i_b1_003_serb, /* name of character set */ + cet_cs_alias_jus_i_b1_003_serb, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_jus_i_b1_003_serb, /* char to UCS-4 value table */ + cet_ucs4_ofs_jus_i_b1_003_serb, /* first non standard character */ + cet_ucs4_cnt_jus_i_b1_003_serb, /* number of values in table */ + + cet_ucs4_to_jus_i_b1_003_serb_links, /* UCS-4 to char links */ + cet_ucs4_to_jus_i_b1_003_serb_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int jus_i_b1_003_serb_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0416, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0408, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0409, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x040a, + 0x040f, 0x0405, 0x0417, 0x0428, 0x0402, 0x040b, 0x0427, 0x005f, + 0x0436, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0458, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0459, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x045a, + 0x045f, 0x0455, 0x0437, 0x0448, 0x0452, 0x045b, 0x0447, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/keybcs2.h b/cet/keybcs2.h new file mode 100644 index 000000000..29b0cbb1b --- /dev/null +++ b/cet/keybcs2.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KEYBCS2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef keybcs2_h +#define keybcs2_h + +#define cet_cs_name_keybcs2 "KEYBCS2" + +const char *cet_cs_alias_keybcs2[] = +{ + "KEYBCS2", "Kamenicky", NULL +}; + +#define cet_ucs4_ofs_keybcs2 128 +#define cet_ucs4_cnt_keybcs2 128 + +const int cet_ucs4_map_keybcs2[cet_ucs4_cnt_keybcs2] = +{ + 0x010c, 0x00fc, 0x00e9, 0x010f, 0x00e4, 0x010e, 0x0164, 0x010d, + 0x011b, 0x011a, 0x0139, 0x00cd, 0x013e, 0x013a, 0x00c4, 0x00c1, + 0x00c9, 0x017e, 0x017d, 0x00f4, 0x00f6, 0x00d3, 0x016f, 0x00da, + 0x00fd, 0x00d6, 0x00dc, 0x0160, 0x013d, 0x00dd, 0x0158, 0x0165, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0148, 0x0147, 0x016e, 0x00d4, + 0x0161, 0x0159, 0x0155, 0x0154, 0x00bc, 0x00a7, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2219, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; + +#define cet_ucs4_to_keybcs2_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_keybcs2_links[cet_ucs4_to_keybcs2_ct] = +{ + {0x00a0, 0xff} /* space */, + {0x00a7, 0xad} /* sign */, + {0x00ab, 0xae} /* double angle quotation mark */, + {0x00b1, 0xf1} /* sign */, + {0x00b2, 0xfd} /* two */, + {0x00b7, 0xf9} /* dot */, + {0x00bb, 0xaf} /* double angle quotation mark */, + {0x00bc, 0xac} /* fraction one quarter */, + {0x00c1, 0x8f} /* capital letter a with acute */, + {0x00c4, 0x8e} /* capital letter a with diaeresis */, + {0x00c9, 0x90} /* capital letter e with acute */, + {0x00cd, 0x8b} /* capital letter i with acute */, + {0x00d3, 0x95} /* capital letter o with acute */, + {0x00d4, 0xa7} /* capital letter o with circumflex */, + {0x00d6, 0x99} /* capital letter o with diaeresis */, + {0x00da, 0x97} /* capital letter u with acute */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0x9d} /* capital letter y with acute */, + {0x00e1, 0xa0} /* small letter a with acute */, + {0x00e4, 0x84} /* small letter a with diaeresis */, + {0x00e9, 0x82} /* small letter e with acute */, + {0x00ed, 0xa1} /* small letter i with acute */, + {0x00f3, 0xa2} /* small letter o with acute */, + {0x00f4, 0x93} /* small letter o with circumflex */, + {0x00f6, 0x94} /* small letter o with diaeresis */, + {0x00f7, 0xf6} /* sign */, + {0x00fa, 0xa3} /* small letter u with acute */, + {0x00fc, 0x81} /* small letter u with diaeresis */, + {0x00fd, 0x98} /* small letter y with acute */, + {0x010c, 0x80} /* capital letter c with caron */, + {0x010d, 0x87} /* small letter c with caron */, + {0x010e, 0x85} /* capital letter d with caron */, + {0x010f, 0x83} /* small letter d with caron */, + {0x011a, 0x89} /* capital letter e with caron */, + {0x011b, 0x88} /* small letter e with caron */, + {0x0139, 0x8a} /* capital letter l with acute */, + {0x013a, 0x8d} /* small letter l with acute */, + {0x013d, 0x9c} /* capital letter l with caron */, + {0x013e, 0x8c} /* small letter l with caron */, + {0x0147, 0xa5} /* capital letter n with caron */, + {0x0148, 0xa4} /* small letter n with caron */, + {0x0154, 0xab} /* capital letter r with acute */, + {0x0155, 0xaa} /* small letter r with acute */, + {0x0158, 0x9e} /* capital letter r with caron */, + {0x0159, 0xa9} /* small letter r with caron */, + {0x0160, 0x9b} /* capital letter s with caron */, + {0x0161, 0xa8} /* small letter s with caron */, + {0x0164, 0x86} /* capital letter t with caron */, + {0x0165, 0x9f} /* small letter t with caron */, + {0x016e, 0xa6} /* capital letter u with ring above */, + {0x016f, 0x96} /* small letter u with ring above */, + {0x017d, 0x92} /* capital letter z with caron */, + {0x017e, 0x91} /* small letter z with caron */, + {0x0393, 0xe2} /* capital letter gamma */, + {0x0398, 0xe9} /* capital letter theta */, + {0x03a3, 0xe4} /* capital letter sigma */, + {0x03a6, 0xe8} /* capital letter phi */, + {0x03a9, 0xea} /* capital letter omega */, + {0x03b1, 0xe0} /* small letter alpha */, + {0x03b2, 0xe1} /* small letter beta */, + {0x03b4, 0xeb} /* small letter delta */, + {0x03b5, 0xee} /* small letter epsilon */, + {0x03bc, 0xe6} /* small letter mu */, + {0x03c0, 0xe3} /* small letter pi */, + {0x03c3, 0xe5} /* small letter sigma */, + {0x03c4, 0xe7} /* small letter tau */, + {0x207f, 0xfc} /* latin small letter n */, + {0x2205, 0xed} /* set */, + {0x2218, 0xf8} /* operator */, + {0x2219, 0xfa} /* operator */, + {0x221a, 0xfb} /* root */, + {0x221e, 0xec} /* infinity */, + {0x2229, 0xef} /* intersection */, + {0x2248, 0xf7} /* equal to */, + {0x2261, 0xf0} /* to */, + {0x2264, 0xf3} /* or equal to */, + {0x2265, 0xf2} /* or equal to */, + {0x2320, 0xf4} /* half integral */, + {0x2321, 0xf5} /* half integral */, + {0x2500, 0xc4} /* drawings light horizontal */, + {0x2502, 0xb3} /* drawings light vertical */, + {0x250c, 0xda} /* drawings light down and right */, + {0x2510, 0xbf} /* drawings light down and left */, + {0x2514, 0xc0} /* drawings light up and right */, + {0x2518, 0xd9} /* drawings light up and left */, + {0x251c, 0xc3} /* drawings light vertical and right */, + {0x2524, 0xb4} /* drawings light vertical and left */, + {0x252c, 0xc2} /* drawings light down and horizontal */, + {0x2534, 0xc1} /* drawings light up and horizontal */, + {0x253c, 0xc5} /* drawings light vertical and horizontal */, + {0x2550, 0xcd} /* drawings heavy horizontal */, + {0x2551, 0xba} /* drawings heavy vertical */, + {0x2552, 0xd5} /* drawings down light and right heavy */, + {0x2553, 0xd6} /* drawings down heavy and right light */, + {0x2554, 0xc9} /* drawings heavy down and right */, + {0x2555, 0xb8} /* drawings down light and left heavy */, + {0x2556, 0xb7} /* drawings down heavy and left light */, + {0x2557, 0xbb} /* drawings heavy down and left */, + {0x2558, 0xd4} /* drawings up light and right heavy */, + {0x2559, 0xd3} /* drawings up heavy and right light */, + {0x255a, 0xc8} /* drawings heavy up and right */, + {0x255b, 0xbe} /* drawings up light and left heavy */, + {0x255c, 0xbd} /* drawings up heavy and left light */, + {0x255d, 0xbc} /* drawings heavy up and left */, + {0x255e, 0xc6} /* drawings vertical light and right heavy */, + {0x255f, 0xc7} /* drawings vertical heavy and right light */, + {0x2560, 0xcc} /* drawings heavy vertical and right */, + {0x2561, 0xb5} /* drawings vertical light and left heavy */, + {0x2562, 0xb6} /* drawings vertical heavy and left light */, + {0x2563, 0xb9} /* drawings heavy vertical and left */, + {0x2564, 0xd1} /* drawings down light and horizontal heavy */, + {0x2565, 0xd2} /* drawings down heavy and horizontal light */, + {0x2566, 0xcb} /* drawings heavy down and horizontal */, + {0x2567, 0xcf} /* drawings up light and horizontal heavy */, + {0x2568, 0xd0} /* drawings up heavy and horizontal light */, + {0x2569, 0xca} /* drawings heavy up and horizontal */, + {0x256a, 0xd8} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xd7} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xce} /* drawings heavy vertical and horizontal */, + {0x2580, 0xdf} /* half block */, + {0x2584, 0xdc} /* half block */, + {0x2588, 0xdb} /* block */, + {0x258c, 0xdd} /* half block */, + {0x2590, 0xde} /* half block */, + {0x2591, 0xb0} /* shade */, + {0x2592, 0xb1} /* shade */, + {0x2593, 0xb2} /* shade */, + {0x25a0, 0xfe} /* square */ +}; + +/* +#define cet_ucs4_to_keybcs2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_keybcs2_extra[cet_ucs4_to_keybcs2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_keybcs2 = /* defined in cet.h */ +{ + cet_cs_name_keybcs2, /* name of character set */ + cet_cs_alias_keybcs2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_keybcs2, /* char to UCS-4 value table */ + cet_ucs4_ofs_keybcs2, /* first non standard character */ + cet_ucs4_cnt_keybcs2, /* number of values in table */ + + cet_ucs4_to_keybcs2_links, /* UCS-4 to char links */ + cet_ucs4_to_keybcs2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int keybcs2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x010c, 0x00fc, 0x00e9, 0x010f, 0x00e4, 0x010e, 0x0164, 0x010d, + 0x011b, 0x011a, 0x0139, 0x00cd, 0x013e, 0x013a, 0x00c4, 0x00c1, + 0x00c9, 0x017e, 0x017d, 0x00f4, 0x00f6, 0x00d3, 0x016f, 0x00da, + 0x00fd, 0x00d6, 0x00dc, 0x0160, 0x013d, 0x00dd, 0x0158, 0x0165, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0148, 0x0147, 0x016e, 0x00d4, + 0x0161, 0x0159, 0x0155, 0x0154, 0x00bc, 0x00a7, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x03bc, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x2205, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x2218, 0x00b7, 0x2219, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 +}; +*/ + +#endif diff --git a/cet/koi8_r.h b/cet/koi8_r.h new file mode 100644 index 000000000..36f63e453 --- /dev/null +++ b/cet/koi8_r.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI8-R" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi8_r_h +#define koi8_r_h + +#define cet_cs_name_koi8_r "KOI8-R" + +const char *cet_cs_alias_koi8_r[] = +{ + "KOI8-R", "csKOI8R", NULL +}; + +#define cet_ucs4_ofs_koi8_r 128 +#define cet_ucs4_cnt_koi8_r 128 + +const int cet_ucs4_map_koi8_r[cet_ucs4_cnt_koi8_r] = +{ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2022, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; + +#define cet_ucs4_to_koi8_r_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_koi8_r_links[cet_ucs4_to_koi8_r_ct] = +{ + {0x00a0, 0x9a} /* space */, + {0x00a9, 0xbf} /* sign */, + {0x00b0, 0x9c} /* sign */, + {0x00b2, 0x9d} /* two */, + {0x00b7, 0x9e} /* dot */, + {0x00f7, 0x9f} /* sign */, + {0x0401, 0xb3} /* capital letter io */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042a, 0xff} /* capital letter hard sign */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x2022, 0x95} /* puce */, + {0x221a, 0x96} /* root */, + {0x2248, 0x97} /* equal to */, + {0x2264, 0x98} /* or equal to */, + {0x2265, 0x99} /* or equal to */, + {0x2320, 0x93} /* half integral */, + {0x2321, 0x9b} /* half integral */, + {0x2500, 0x80} /* drawings light horizontal */, + {0x2502, 0x81} /* drawings light vertical */, + {0x250c, 0x82} /* drawings light down and right */, + {0x2510, 0x83} /* drawings light down and left */, + {0x2514, 0x84} /* drawings light up and right */, + {0x2518, 0x85} /* drawings light up and left */, + {0x251c, 0x86} /* drawings light vertical and right */, + {0x2524, 0x87} /* drawings light vertical and left */, + {0x252c, 0x88} /* drawings light down and horizontal */, + {0x2534, 0x89} /* drawings light up and horizontal */, + {0x253c, 0x8a} /* drawings light vertical and horizontal */, + {0x2550, 0xa0} /* drawings heavy horizontal */, + {0x2551, 0xa1} /* drawings heavy vertical */, + {0x2552, 0xa2} /* drawings down light and right heavy */, + {0x2553, 0xa4} /* drawings down heavy and right light */, + {0x2554, 0xa5} /* drawings heavy down and right */, + {0x2555, 0xa6} /* drawings down light and left heavy */, + {0x2556, 0xa7} /* drawings down heavy and left light */, + {0x2557, 0xa8} /* drawings heavy down and left */, + {0x2558, 0xa9} /* drawings up light and right heavy */, + {0x2559, 0xaa} /* drawings up heavy and right light */, + {0x255a, 0xab} /* drawings heavy up and right */, + {0x255b, 0xac} /* drawings up light and left heavy */, + {0x255c, 0xad} /* drawings up heavy and left light */, + {0x255d, 0xae} /* drawings heavy up and left */, + {0x255e, 0xaf} /* drawings vertical light and right heavy */, + {0x255f, 0xb0} /* drawings vertical heavy and right light */, + {0x2560, 0xb1} /* drawings heavy vertical and right */, + {0x2561, 0xb2} /* drawings vertical light and left heavy */, + {0x2562, 0xb4} /* drawings vertical heavy and left light */, + {0x2563, 0xb5} /* drawings heavy vertical and left */, + {0x2564, 0xb6} /* drawings down light and horizontal heavy */, + {0x2565, 0xb7} /* drawings down heavy and horizontal light */, + {0x2566, 0xb8} /* drawings heavy down and horizontal */, + {0x2567, 0xb9} /* drawings up light and horizontal heavy */, + {0x2568, 0xba} /* drawings up heavy and horizontal light */, + {0x2569, 0xbb} /* drawings heavy up and horizontal */, + {0x256a, 0xbc} /* drawings vertical light and horizontal heavy */, + {0x256b, 0xbd} /* drawings vertical heavy and horizontal light */, + {0x256c, 0xbe} /* drawings heavy vertical and horizontal */, + {0x2580, 0x8b} /* half block */, + {0x2584, 0x8c} /* half block */, + {0x2588, 0x8d} /* block */, + {0x258c, 0x8e} /* half block */, + {0x2590, 0x8f} /* half block */, + {0x2591, 0x90} /* shade */, + {0x2592, 0x91} /* shade */, + {0x2593, 0x92} /* shade */, + {0x25a0, 0x94} /* square */ +}; + +/* +#define cet_ucs4_to_koi8_r_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi8_r_extra[cet_ucs4_to_koi8_r_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi8_r = /* defined in cet.h */ +{ + cet_cs_name_koi8_r, /* name of character set */ + cet_cs_alias_koi8_r, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi8_r, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi8_r, /* first non standard character */ + cet_ucs4_cnt_koi8_r, /* number of values in table */ + + cet_ucs4_to_koi8_r_links, /* UCS-4 to char links */ + cet_ucs4_to_koi8_r_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi8_r_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2022, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; +*/ + +#endif diff --git a/cet/koi8_ru.h b/cet/koi8_ru.h new file mode 100644 index 000000000..7800847bc --- /dev/null +++ b/cet/koi8_ru.h @@ -0,0 +1,256 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI8-RU" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi8_ru_h +#define koi8_ru_h + +#define cet_cs_name_koi8_ru "KOI8-RU" + +const char *cet_cs_alias_koi8_ru[] = +{ + "KOI8-RU", NULL +}; + +#define cet_ucs4_ofs_koi8_ru 128 +#define cet_ucs4_cnt_koi8_ru 128 + +const int cet_ucs4_map_koi8_ru[cet_ucs4_cnt_koi8_ru] = +{ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x201c, 0x25a0, 0x2022, 0x201d, 0x2014, + 0x2116, 0x2122, 0x00a0, 0x00bb, 0x00ae, 0x00ab, 0x00b7, 0x00a4, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x045e, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x040e, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; + +#define cet_ucs4_to_koi8_ru_ct 128 + +const cet_ucs4_link_t cet_ucs4_to_koi8_ru_links[cet_ucs4_to_koi8_ru_ct] = +{ + {0x00a0, 0x9a} /* space */, + {0x00a4, 0x9f} /* sign */, + {0x00a9, 0xbf} /* sign */, + {0x00ab, 0x9d} /* double angle quotation mark */, + {0x00ae, 0x9c} /* sign */, + {0x00b7, 0x9e} /* dot */, + {0x00bb, 0x9b} /* double angle quotation mark */, + {0x0401, 0xb3} /* capital letter io */, + {0x0404, 0xb4} /* capital letter ukrainian ie */, + {0x0406, 0xb6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xb7} /* capital letter yi (ukrainian) */, + {0x040e, 0xbe} /* capital letter short u (byelorussian) */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042a, 0xff} /* capital letter hard sign */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x0454, 0xa4} /* small letter ukrainian ie */, + {0x0456, 0xa6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xa7} /* small letter yi (ukrainian) */, + {0x045e, 0xae} /* small letter short u (byelorussian) */, + {0x0490, 0xbd} /* capital letter ghe with upturn */, + {0x0491, 0xad} /* small letter ghe with upturn */, + {0x2014, 0x97} /* dash */, + {0x201c, 0x93} /* double quotation mark */, + {0x201d, 0x96} /* double quotation mark */, + {0x2022, 0x95} /* puce */, + {0x2116, 0x98} /* sign */, + {0x2122, 0x99} /* mark sign */, + {0x2500, 0x80} /* drawings light horizontal */, + {0x2502, 0x81} /* drawings light vertical */, + {0x250c, 0x82} /* drawings light down and right */, + {0x2510, 0x83} /* drawings light down and left */, + {0x2514, 0x84} /* drawings light up and right */, + {0x2518, 0x85} /* drawings light up and left */, + {0x251c, 0x86} /* drawings light vertical and right */, + {0x2524, 0x87} /* drawings light vertical and left */, + {0x252c, 0x88} /* drawings light down and horizontal */, + {0x2534, 0x89} /* drawings light up and horizontal */, + {0x253c, 0x8a} /* drawings light vertical and horizontal */, + {0x2550, 0xa0} /* drawings heavy horizontal */, + {0x2551, 0xa1} /* drawings heavy vertical */, + {0x2552, 0xa2} /* drawings down light and right heavy */, + {0x2554, 0xa5} /* drawings heavy down and right */, + {0x2557, 0xa8} /* drawings heavy down and left */, + {0x2558, 0xa9} /* drawings up light and right heavy */, + {0x2559, 0xaa} /* drawings up heavy and right light */, + {0x255a, 0xab} /* drawings heavy up and right */, + {0x255b, 0xac} /* drawings up light and left heavy */, + {0x255e, 0xaf} /* drawings vertical light and right heavy */, + {0x255f, 0xb0} /* drawings vertical heavy and right light */, + {0x2560, 0xb1} /* drawings heavy vertical and right */, + {0x2561, 0xb2} /* drawings vertical light and left heavy */, + {0x2563, 0xb5} /* drawings heavy vertical and left */, + {0x2566, 0xb8} /* drawings heavy down and horizontal */, + {0x2567, 0xb9} /* drawings up light and horizontal heavy */, + {0x2568, 0xba} /* drawings up heavy and horizontal light */, + {0x2569, 0xbb} /* drawings heavy up and horizontal */, + {0x256a, 0xbc} /* drawings vertical light and horizontal heavy */, + {0x2580, 0x8b} /* half block */, + {0x2584, 0x8c} /* half block */, + {0x2588, 0x8d} /* block */, + {0x258c, 0x8e} /* half block */, + {0x2590, 0x8f} /* half block */, + {0x2591, 0x90} /* shade */, + {0x2592, 0x91} /* shade */, + {0x2593, 0x92} /* shade */, + {0x25a0, 0x94} /* square */ +}; + +/* +#define cet_ucs4_to_koi8_ru_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi8_ru_extra[cet_ucs4_to_koi8_ru_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi8_ru = /* defined in cet.h */ +{ + cet_cs_name_koi8_ru, /* name of character set */ + cet_cs_alias_koi8_ru, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi8_ru, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi8_ru, /* first non standard character */ + cet_ucs4_cnt_koi8_ru, /* number of values in table */ + + cet_ucs4_to_koi8_ru_links, /* UCS-4 to char links */ + cet_ucs4_to_koi8_ru_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi8_ru_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x201c, 0x25a0, 0x2022, 0x201d, 0x2014, + 0x2116, 0x2122, 0x00a0, 0x00bb, 0x00ae, 0x00ab, 0x00b7, 0x00a4, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x045e, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x040e, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a +}; +*/ + +#endif diff --git a/cet/koi8_u.h b/cet/koi8_u.h new file mode 100644 index 000000000..1f3d88cfc --- /dev/null +++ b/cet/koi8_u.h @@ -0,0 +1,238 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI8-U" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi8_u_h +#define koi8_u_h + +#define cet_cs_name_koi8_u "KOI8-U" + +const char *cet_cs_alias_koi8_u[] = +{ + "KOI8-U", NULL +}; + +#define cet_ucs4_ofs_koi8_u 128 +#define cet_ucs4_cnt_koi8_u 112 + +const int cet_ucs4_map_koi8_u[cet_ucs4_cnt_koi8_u] = +{ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e +}; + +#define cet_ucs4_to_koi8_u_ct 112 + +const cet_ucs4_link_t cet_ucs4_to_koi8_u_links[cet_ucs4_to_koi8_u_ct] = +{ + {0x00a0, 0x9a} /* space */, + {0x00a9, 0xbf} /* sign */, + {0x00b0, 0x9c} /* sign */, + {0x00b2, 0x9d} /* two */, + {0x00b7, 0x9e} /* dot */, + {0x00f7, 0x9f} /* sign */, + {0x0401, 0xb3} /* capital letter io */, + {0x0404, 0xb4} /* capital letter ukrainian ie */, + {0x0406, 0xb6} /* capital letter byelorussian-ukrainian i */, + {0x0407, 0xb7} /* capital letter yi (ukrainian) */, + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x042e, 0xe0} /* capital letter yu */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */, + {0x0451, 0xa3} /* small letter io */, + {0x0454, 0xa4} /* small letter ukrainian ie */, + {0x0456, 0xa6} /* small letter byelorussian-ukrainian i */, + {0x0457, 0xa7} /* small letter yi (ukrainian) */, + {0x0490, 0xbd} /* capital letter ghe with upturn */, + {0x0491, 0xad} /* small letter ghe with upturn */, + {0x2219, 0x95} /* operator */, + {0x221a, 0x96} /* root */, + {0x2248, 0x97} /* equal to */, + {0x2264, 0x98} /* or equal to */, + {0x2265, 0x99} /* or equal to */, + {0x2320, 0x93} /* half integral */, + {0x2321, 0x9b} /* half integral */, + {0x2500, 0x80} /* drawings light horizontal */, + {0x2502, 0x81} /* drawings light vertical */, + {0x250c, 0x82} /* drawings light down and right */, + {0x2510, 0x83} /* drawings light down and left */, + {0x2514, 0x84} /* drawings light up and right */, + {0x2518, 0x85} /* drawings light up and left */, + {0x251c, 0x86} /* drawings light vertical and right */, + {0x2524, 0x87} /* drawings light vertical and left */, + {0x252c, 0x88} /* drawings light down and horizontal */, + {0x2534, 0x89} /* drawings light up and horizontal */, + {0x253c, 0x8a} /* drawings light vertical and horizontal */, + {0x2550, 0xa0} /* drawings heavy horizontal */, + {0x2551, 0xa1} /* drawings heavy vertical */, + {0x2552, 0xa2} /* drawings down light and right heavy */, + {0x2554, 0xa5} /* drawings heavy down and right */, + {0x2557, 0xa8} /* drawings heavy down and left */, + {0x2558, 0xa9} /* drawings up light and right heavy */, + {0x2559, 0xaa} /* drawings up heavy and right light */, + {0x255a, 0xab} /* drawings heavy up and right */, + {0x255b, 0xac} /* drawings up light and left heavy */, + {0x255d, 0xae} /* drawings heavy up and left */, + {0x255e, 0xaf} /* drawings vertical light and right heavy */, + {0x255f, 0xb0} /* drawings vertical heavy and right light */, + {0x2560, 0xb1} /* drawings heavy vertical and right */, + {0x2561, 0xb2} /* drawings vertical light and left heavy */, + {0x2563, 0xb5} /* drawings heavy vertical and left */, + {0x2566, 0xb8} /* drawings heavy down and horizontal */, + {0x2567, 0xb9} /* drawings up light and horizontal heavy */, + {0x2568, 0xba} /* drawings up heavy and horizontal light */, + {0x2569, 0xbb} /* drawings heavy up and horizontal */, + {0x256a, 0xbc} /* drawings vertical light and horizontal heavy */, + {0x256c, 0xbe} /* drawings heavy vertical and horizontal */, + {0x2580, 0x8b} /* half block */, + {0x2584, 0x8c} /* half block */, + {0x2588, 0x8d} /* block */, + {0x258c, 0x8e} /* half block */, + {0x2590, 0x8f} /* half block */, + {0x2591, 0x90} /* shade */, + {0x2592, 0x91} /* shade */, + {0x2593, 0x92} /* shade */, + {0x25a0, 0x94} /* square */ +}; + +/* +#define cet_ucs4_to_koi8_u_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi8_u_extra[cet_ucs4_to_koi8_u_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi8_u = /* defined in cet.h */ +{ + cet_cs_name_koi8_u, /* name of character set */ + cet_cs_alias_koi8_u, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi8_u, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi8_u, /* first non standard character */ + cet_ucs4_cnt_koi8_u, /* number of values in table */ + + cet_ucs4_to_koi8_u_links, /* UCS-4 to char links */ + cet_ucs4_to_koi8_u_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi8_u_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/koi_7.h b/cet/koi_7.h new file mode 100644 index 000000000..7e94ce3cb --- /dev/null +++ b/cet/koi_7.h @@ -0,0 +1,156 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI-7" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi_7_h +#define koi_7_h + +#define cet_cs_name_koi_7 "KOI-7" + +const char *cet_cs_alias_koi_7[] = +{ + "KOI-7", NULL +}; + +#define cet_ucs4_ofs_koi_7 36 +#define cet_ucs4_cnt_koi_7 92 + +const int cet_ucs4_map_koi_7[cet_ucs4_cnt_koi_7] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x042e, 0x0410, 0x0411, 0x0426, + 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041a, + 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x042f, 0x0420, 0x0421, + 0x0422, 0x0423, 0x0416, 0x0412, 0x042c, 0x042b, 0x0417, 0x0428, + 0x042d, 0x0429, 0x0427, 0x007f +}; + +#define cet_ucs4_to_koi_7_ct 32 + +const cet_ucs4_link_t cet_ucs4_to_koi_7_links[cet_ucs4_to_koi_7_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0410, 0x61} /* capital letter a */, + {0x0411, 0x62} /* capital letter be */, + {0x0412, 0x77} /* capital letter ve */, + {0x0413, 0x67} /* capital letter ghe */, + {0x0414, 0x64} /* capital letter de */, + {0x0415, 0x65} /* capital letter ie */, + {0x0416, 0x76} /* capital letter zhe */, + {0x0417, 0x7a} /* capital letter ze */, + {0x0418, 0x69} /* capital letter i */, + {0x0419, 0x6a} /* capital letter short i */, + {0x041a, 0x6b} /* capital letter ka */, + {0x041b, 0x6c} /* capital letter el */, + {0x041c, 0x6d} /* capital letter em */, + {0x041d, 0x6e} /* capital letter en */, + {0x041e, 0x6f} /* capital letter o */, + {0x041f, 0x70} /* capital letter pe */, + {0x0420, 0x72} /* capital letter er */, + {0x0421, 0x73} /* capital letter es */, + {0x0422, 0x74} /* capital letter te */, + {0x0423, 0x75} /* capital letter u */, + {0x0424, 0x66} /* capital letter ef */, + {0x0425, 0x68} /* capital letter ha */, + {0x0426, 0x63} /* capital letter tse */, + {0x0427, 0x7e} /* capital letter che */, + {0x0428, 0x7b} /* capital letter sha */, + {0x0429, 0x7d} /* capital letter shcha */, + {0x042b, 0x79} /* capital letter yeru */, + {0x042c, 0x78} /* capital letter soft sign */, + {0x042d, 0x7c} /* capital letter e */, + {0x042e, 0x60} /* capital letter yu */, + {0x042f, 0x71} /* capital letter ya */ +}; + +/* +#define cet_ucs4_to_koi_7_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi_7_extra[cet_ucs4_to_koi_7_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi_7 = /* defined in cet.h */ +{ + cet_cs_name_koi_7, /* name of character set */ + cet_cs_alias_koi_7, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi_7, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi_7, /* first non standard character */ + cet_ucs4_cnt_koi_7, /* number of values in table */ + + cet_ucs4_to_koi_7_links, /* UCS-4 to char links */ + cet_ucs4_to_koi_7_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi_7_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/koi_8.h b/cet/koi_8.h new file mode 100644 index 000000000..8b4795be9 --- /dev/null +++ b/cet/koi_8.h @@ -0,0 +1,191 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI-8" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi_8_h +#define koi_8_h + +#define cet_cs_name_koi_8 "KOI-8" + +const char *cet_cs_alias_koi_8[] = +{ + "KOI-8", "GOST_19768-74", NULL +}; + +#define cet_ucs4_ofs_koi_8 128 +#define cet_ucs4_cnt_koi_8 127 + +const int cet_ucs4_map_koi_8[cet_ucs4_cnt_koi_8] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427 +}; + +#define cet_ucs4_to_koi_8_ct 63 + +const cet_ucs4_link_t cet_ucs4_to_koi_8_links[cet_ucs4_to_koi_8_ct] = +{ + {0x0410, 0xe1} /* capital letter a */, + {0x0411, 0xe2} /* capital letter be */, + {0x0412, 0xf7} /* capital letter ve */, + {0x0413, 0xe7} /* capital letter ghe */, + {0x0414, 0xe4} /* capital letter de */, + {0x0415, 0xe5} /* capital letter ie */, + {0x0416, 0xf6} /* capital letter zhe */, + {0x0417, 0xfa} /* capital letter ze */, + {0x0418, 0xe9} /* capital letter i */, + {0x0419, 0xea} /* capital letter short i */, + {0x041a, 0xeb} /* capital letter ka */, + {0x041b, 0xec} /* capital letter el */, + {0x041c, 0xed} /* capital letter em */, + {0x041d, 0xee} /* capital letter en */, + {0x041e, 0xef} /* capital letter o */, + {0x041f, 0xf0} /* capital letter pe */, + {0x0420, 0xf2} /* capital letter er */, + {0x0421, 0xf3} /* capital letter es */, + {0x0422, 0xf4} /* capital letter te */, + {0x0423, 0xf5} /* capital letter u */, + {0x0424, 0xe6} /* capital letter ef */, + {0x0425, 0xe8} /* capital letter ha */, + {0x0426, 0xe3} /* capital letter tse */, + {0x0427, 0xfe} /* capital letter che */, + {0x0428, 0xfb} /* capital letter sha */, + {0x0429, 0xfd} /* capital letter shcha */, + {0x042b, 0xf9} /* capital letter yeru */, + {0x042c, 0xf8} /* capital letter soft sign */, + {0x042d, 0xfc} /* capital letter e */, + {0x042e, 0xe0} /* capital letter yu */, + {0x042f, 0xf1} /* capital letter ya */, + {0x0430, 0xc1} /* small letter a */, + {0x0431, 0xc2} /* small letter be */, + {0x0432, 0xd7} /* small letter ve */, + {0x0433, 0xc7} /* small letter ghe */, + {0x0434, 0xc4} /* small letter de */, + {0x0435, 0xc5} /* small letter ie */, + {0x0436, 0xd6} /* small letter zhe */, + {0x0437, 0xda} /* small letter ze */, + {0x0438, 0xc9} /* small letter i */, + {0x0439, 0xca} /* small letter short i */, + {0x043a, 0xcb} /* small letter ka */, + {0x043b, 0xcc} /* small letter el */, + {0x043c, 0xcd} /* small letter em */, + {0x043d, 0xce} /* small letter en */, + {0x043e, 0xcf} /* small letter o */, + {0x043f, 0xd0} /* small letter pe */, + {0x0440, 0xd2} /* small letter er */, + {0x0441, 0xd3} /* small letter es */, + {0x0442, 0xd4} /* small letter te */, + {0x0443, 0xd5} /* small letter u */, + {0x0444, 0xc6} /* small letter ef */, + {0x0445, 0xc8} /* small letter ha */, + {0x0446, 0xc3} /* small letter tse */, + {0x0447, 0xde} /* small letter che */, + {0x0448, 0xdb} /* small letter sha */, + {0x0449, 0xdd} /* small letter shcha */, + {0x044a, 0xdf} /* small letter hard sign */, + {0x044b, 0xd9} /* small letter yeru */, + {0x044c, 0xd8} /* small letter soft sign */, + {0x044d, 0xdc} /* small letter e */, + {0x044e, 0xc0} /* small letter yu */, + {0x044f, 0xd1} /* small letter ya */ +}; + +/* +#define cet_ucs4_to_koi_8_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi_8_extra[cet_ucs4_to_koi_8_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi_8 = /* defined in cet.h */ +{ + cet_cs_name_koi_8, /* name of character set */ + cet_cs_alias_koi_8, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi_8, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi_8, /* first non standard character */ + cet_ucs4_cnt_koi_8, /* number of values in table */ + + cet_ucs4_to_koi_8_links, /* UCS-4 to char links */ + cet_ucs4_to_koi_8_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi_8_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, -1 +}; +*/ + +#endif diff --git a/cet/koi_8_cs2.h b/cet/koi_8_cs2.h new file mode 100644 index 000000000..3398b91e6 --- /dev/null +++ b/cet/koi_8_cs2.h @@ -0,0 +1,222 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KOI-8_CS2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef koi_8_cs2_h +#define koi_8_cs2_h + +#define cet_cs_name_koi_8_cs2 "KOI-8_CS2" + +const char *cet_cs_alias_koi_8_cs2[] = +{ + "KOI-8_CS2", NULL +}; + +#define cet_ucs4_ofs_koi_8_cs2 36 +#define cet_ucs4_cnt_koi_8_cs2 219 + +const int cet_ucs4_map_koi_8_cs2[cet_ucs4_cnt_koi_8_cs2] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, + 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092, 0x0093, + 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, + 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, -1, 0x00b4, -1, + 0x007e, -1, 0x02d8, 0x02d9, 0x00a8, -1, 0x02da, 0x00b8, + -1, 0x02dd, 0x02db, 0x02c7, 0x00a9, 0x2122, 0x250c, 0x2510, + 0x2514, 0x2518, 0x2500, 0x2193, 0x03a9, 0x00a7, 0x03b1, 0x03b3, + 0x03b5, 0x03bc, 0x03c0, 0x03c9, 0x00e0, 0x00e1, 0x01ce, 0x010d, + 0x010f, 0x011b, 0x0155, -1, 0x00fc, 0x00ed, 0x016f, 0x013a, + 0x013e, 0x00f6, 0x0148, 0x00f3, 0x00f4, 0x00e4, 0x0159, 0x0161, + 0x0165, 0x00fa, 0x00eb, 0x00e9, 0x0171, 0x00fd, 0x017e, -1, + -1, 0x0151, 0x0117, 0x00df, 0x00c0, 0x00c1, 0x01cd, 0x010c, + 0x010e, 0x011a, 0x0154, -1, 0x00dc, 0x00cd, 0x016e, 0x0139, + 0x013d, 0x00d6, 0x0147, 0x00d3, 0x00d4, 0x00c4, 0x0158, 0x0160, + 0x0164, 0x00da, 0x00cb, 0x00c9, 0x0170, 0x00dd, 0x017d, -1, + -1, 0x0150, 0x0116 +}; + +#define cet_ucs4_to_koi_8_cs2_ct 82 + +const cet_ucs4_link_t cet_ucs4_to_koi_8_cs2_links[cet_ucs4_to_koi_8_cs2_ct] = +{ + {0x007e, 0xa4} /* tilde */, + {0x00a4, 0x24} /* sign */, + {0x00a7, 0xb9} /* sign */, + {0x00a9, 0xb0} /* sign */, + {0x00b4, 0xa2} /* accent */, + {0x00b8, 0xab} /* cedilla */, + {0x00c0, 0xe0} /* capital letter a with grave */, + {0x00c1, 0xe1} /* capital letter a with acute */, + {0x00c4, 0xf1} /* capital letter a with diaeresis */, + {0x00c9, 0xf7} /* capital letter e with acute */, + {0x00cb, 0xf6} /* capital letter e with diaeresis */, + {0x00cd, 0xe9} /* capital letter i with acute */, + {0x00d3, 0xef} /* capital letter o with acute */, + {0x00d4, 0xf0} /* capital letter o with circumflex */, + {0x00d6, 0xed} /* capital letter o with diaeresis */, + {0x00da, 0xf5} /* capital letter u with acute */, + {0x00dc, 0xe8} /* capital letter u with diaeresis */, + {0x00dd, 0xf9} /* capital letter y with acute */, + {0x00e0, 0xc0} /* small letter a with grave */, + {0x00e1, 0xc1} /* small letter a with acute */, + {0x00e4, 0xd1} /* small letter a with diaeresis */, + {0x00e9, 0xd7} /* small letter e with acute */, + {0x00eb, 0xd6} /* small letter e with diaeresis */, + {0x00ed, 0xc9} /* small letter i with acute */, + {0x00f3, 0xcf} /* small letter o with acute */, + {0x00f4, 0xd0} /* small letter o with circumflex */, + {0x00f6, 0xcd} /* small letter o with diaeresis */, + {0x00fa, 0xd5} /* small letter u with acute */, + {0x00fc, 0xc8} /* small letter u with diaeresis */, + {0x00fd, 0xd9} /* small letter y with acute */, + {0x010c, 0xe3} /* capital letter c with caron */, + {0x010d, 0xc3} /* small letter c with caron */, + {0x010e, 0xe4} /* capital letter d with caron */, + {0x010f, 0xc4} /* small letter d with caron */, + {0x0116, 0xfe} /* capital letter e with dot above */, + {0x0117, 0xde} /* small letter e with dot above */, + {0x011a, 0xe5} /* capital letter e with caron */, + {0x011b, 0xc5} /* small letter e with caron */, + {0x0139, 0xeb} /* capital letter l with acute */, + {0x013a, 0xcb} /* small letter l with acute */, + {0x013d, 0xec} /* capital letter l with caron */, + {0x013e, 0xcc} /* small letter l with caron */, + {0x0147, 0xee} /* capital letter n with caron */, + {0x0148, 0xce} /* small letter n with caron */, + {0x0150, 0xfd} /* capital letter o with double acute */, + {0x0151, 0xdd} /* small letter o with double acute */, + {0x0154, 0xe6} /* capital letter r with acute */, + {0x0155, 0xc6} /* small letter r with acute */, + {0x0158, 0xf2} /* capital letter r with caron */, + {0x0159, 0xd2} /* small letter r with caron */, + {0x0160, 0xf3} /* capital letter s with caron */, + {0x0161, 0xd3} /* small letter s with caron */, + {0x0164, 0xf4} /* capital letter t with caron */, + {0x0165, 0xd4} /* small letter t with caron */, + {0x016e, 0xea} /* capital letter u with ring above */, + {0x016f, 0xca} /* small letter u with ring above */, + {0x0170, 0xf8} /* capital letter u with double acute */, + {0x0171, 0xd8} /* small letter u with double acute */, + {0x017d, 0xfa} /* capital letter z with caron */, + {0x017e, 0xda} /* small letter z with caron */, + {0x01cd, 0xe2} /* capital letter a with caron */, + {0x01ce, 0xc2} /* small letter a with caron */, + {0x02c7, 0xaf} /* caron */, + {0x02d8, 0xa6} /* breve */, + {0x02d9, 0xa7} /* above */, + {0x02da, 0xaa} /* above */, + {0x02db, 0xae} /* ogonek */, + {0x02dd, 0xad} /* acute accent */, + {0x03a9, 0xb8} /* capital letter omega */, + {0x03b1, 0xba} /* small letter alpha */, + {0x03b3, 0xbb} /* small letter gamma */, + {0x03b5, 0xbc} /* small letter epsilon */, + {0x03bc, 0xbd} /* small letter mu */, + {0x03c0, 0xbe} /* small letter pi */, + {0x03c9, 0xbf} /* small letter omega */, + {0x2122, 0xb1} /* mark sign */, + {0x2193, 0xb7} /* arrow */, + {0x2500, 0xb6} /* drawings light horizontal */, + {0x250c, 0xb2} /* drawings light down and right */, + {0x2510, 0xb3} /* drawings light down and left */, + {0x2514, 0xb4} /* drawings light up and right */, + {0x2518, 0xb5} /* drawings light up and left */ +}; + +/* +#define cet_ucs4_to_koi_8_cs2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_koi_8_cs2_extra[cet_ucs4_to_koi_8_cs2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_koi_8_cs2 = /* defined in cet.h */ +{ + cet_cs_name_koi_8_cs2, /* name of character set */ + cet_cs_alias_koi_8_cs2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_koi_8_cs2, /* char to UCS-4 value table */ + cet_ucs4_ofs_koi_8_cs2, /* first non standard character */ + cet_ucs4_cnt_koi_8_cs2, /* number of values in table */ + + cet_ucs4_to_koi_8_cs2_links, /* UCS-4 to char links */ + cet_ucs4_to_koi_8_cs2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int koi_8_cs2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, -1, 0x00b4, -1, 0x007e, -1, 0x02d8, 0x02d9, + 0x00a8, -1, 0x02da, 0x00b8, -1, 0x02dd, 0x02db, 0x02c7, + 0x00a9, 0x2122, 0x250c, 0x2510, 0x2514, 0x2518, 0x2500, 0x2193, + 0x03a9, 0x00a7, 0x03b1, 0x03b3, 0x03b5, 0x03bc, 0x03c0, 0x03c9, + 0x00e0, 0x00e1, 0x01ce, 0x010d, 0x010f, 0x011b, 0x0155, -1, + 0x00fc, 0x00ed, 0x016f, 0x013a, 0x013e, 0x00f6, 0x0148, 0x00f3, + 0x00f4, 0x00e4, 0x0159, 0x0161, 0x0165, 0x00fa, 0x00eb, 0x00e9, + 0x0171, 0x00fd, 0x017e, -1, -1, 0x0151, 0x0117, 0x00df, + 0x00c0, 0x00c1, 0x01cd, 0x010c, 0x010e, 0x011a, 0x0154, -1, + 0x00dc, 0x00cd, 0x016e, 0x0139, 0x013d, 0x00d6, 0x0147, 0x00d3, + 0x00d4, 0x00c4, 0x0158, 0x0160, 0x0164, 0x00da, 0x00cb, 0x00c9, + 0x0170, 0x00dd, 0x017d, -1, -1, 0x0150, 0x0116, -1 +}; +*/ + +#endif diff --git a/cet/ksc5636.h b/cet/ksc5636.h new file mode 100644 index 000000000..ff513c529 --- /dev/null +++ b/cet/ksc5636.h @@ -0,0 +1,118 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "KSC5636" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ksc5636_h +#define ksc5636_h + +#define cet_cs_name_ksc5636 "KSC5636" + +const char *cet_cs_alias_ksc5636[] = +{ + "KSC5636", "ISO646-KR", NULL +}; + +#define cet_ucs4_ofs_ksc5636 92 +#define cet_ucs4_cnt_ksc5636 36 + +const int cet_ucs4_map_ksc5636[cet_ucs4_cnt_ksc5636] = +{ + 0x20a9, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, + 0x007c, 0x007d, 0x007e, 0x007f +}; + +#define cet_ucs4_to_ksc5636_ct 1 + +const cet_ucs4_link_t cet_ucs4_to_ksc5636_links[cet_ucs4_to_ksc5636_ct] = +{ + {0x20a9, 0x5c} /* sign */ +}; + +/* +#define cet_ucs4_to_ksc5636_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ksc5636_extra[cet_ucs4_to_ksc5636_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ksc5636 = /* defined in cet.h */ +{ + cet_cs_name_ksc5636, /* name of character set */ + cet_cs_alias_ksc5636, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ksc5636, /* char to UCS-4 value table */ + cet_ucs4_ofs_ksc5636, /* first non standard character */ + cet_ucs4_cnt_ksc5636, /* number of values in table */ + + cet_ucs4_to_ksc5636_links, /* UCS-4 to char links */ + cet_ucs4_to_ksc5636_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ksc5636_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x20a9, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/latin_greek_1.h b/cet/latin_greek_1.h new file mode 100644 index 000000000..ffb016353 --- /dev/null +++ b/cet/latin_greek_1.h @@ -0,0 +1,136 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "Latin-greek-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef latin_greek_1_h +#define latin_greek_1_h + +#define cet_cs_name_latin_greek_1 "Latin-greek-1" + +const char *cet_cs_alias_latin_greek_1[] = +{ + "Latin-greek-1", "iso-ir-27", NULL +}; + +#define cet_ucs4_ofs_latin_greek_1 33 +#define cet_ucs4_cnt_latin_greek_1 95 + +const int cet_ucs4_map_latin_greek_1[cet_ucs4_cnt_latin_greek_1] = +{ + 0x039e, 0x0022, 0x0393, 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x03a8, 0x003b, 0x003c, 0x003d, 0x003e, 0x03a0, 0x0394, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x03a9, 0x0398, 0x03a6, 0x039b, 0x03a3, 0x0060, + 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f +}; + +#define cet_ucs4_to_latin_greek_1_ct 12 + +const cet_ucs4_link_t cet_ucs4_to_latin_greek_1_links[cet_ucs4_to_latin_greek_1_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x0393, 0x23} /* capital letter gamma */, + {0x0394, 0x40} /* capital letter delta */, + {0x0398, 0x5c} /* capital letter theta */, + {0x039b, 0x5e} /* capital letter lamda */, + {0x039e, 0x21} /* capital letter xi */, + {0x03a0, 0x3f} /* capital letter pi */, + {0x03a3, 0x5f} /* capital letter sigma */, + {0x03a6, 0x5d} /* capital letter phi */, + {0x03a8, 0x3a} /* capital letter psi */, + {0x03a9, 0x5b} /* capital letter omega */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_latin_greek_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_latin_greek_1_extra[cet_ucs4_to_latin_greek_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_latin_greek_1 = /* defined in cet.h */ +{ + cet_cs_name_latin_greek_1, /* name of character set */ + cet_cs_alias_latin_greek_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_latin_greek_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_latin_greek_1, /* first non standard character */ + cet_ucs4_cnt_latin_greek_1, /* number of values in table */ + + cet_ucs4_to_latin_greek_1_links, /* UCS-4 to char links */ + cet_ucs4_to_latin_greek_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int latin_greek_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x039e, 0x0022, 0x0393, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x03a8, 0x003b, 0x003c, 0x003d, 0x003e, 0x03a0, + 0x0394, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x03a9, 0x0398, 0x03a6, 0x039b, 0x03a3, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/mac_is.h b/cet/mac_is.h new file mode 100644 index 000000000..6c0050324 --- /dev/null +++ b/cet/mac_is.h @@ -0,0 +1,248 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "mac-is" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef mac_is_h +#define mac_is_h + +#define cet_cs_name_mac_is "mac-is" + +const char *cet_cs_alias_mac_is[] = +{ + "mac-is", NULL +}; + +#define cet_ucs4_ofs_mac_is 128 +#define cet_ucs4_cnt_mac_is 128 + +const int cet_ucs4_map_mac_is[cet_ucs4_cnt_mac_is] = +{ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2014, 0x2013, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x0110, 0x0111, 0x00de, 0x00fe, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; + +#define cet_ucs4_to_mac_is_ct 120 + +const cet_ucs4_link_t cet_ucs4_to_mac_is_links[cet_ucs4_to_mac_is_ct] = +{ + {0x00a0, 0xca} /* space */, + {0x00a1, 0xc1} /* exclamation mark */, + {0x00a4, 0xdb} /* sign */, + {0x00a5, 0xb4} /* sign */, + {0x00a7, 0xa4} /* sign */, + {0x00a8, 0xac} /* diaeresis */, + {0x00aa, 0xbb} /* ordinal indicator */, + {0x00ab, 0xc7} /* double angle quotation mark */, + {0x00ac, 0xc2} /* sign */, + {0x00ae, 0xa8} /* sign */, + {0x00af, 0xf8} /* macron */, + {0x00b0, 0xa1} /* sign */, + {0x00b4, 0xab} /* accent */, + {0x00b6, 0xa6} /* sign */, + {0x00b7, 0xe1} /* dot */, + {0x00b8, 0xfc} /* cedilla */, + {0x00ba, 0xbc} /* ordinal indicator */, + {0x00bb, 0xc8} /* double angle quotation mark */, + {0x00bf, 0xc0} /* question mark */, + {0x00c0, 0xcb} /* capital letter a with grave */, + {0x00c1, 0xe7} /* capital letter a with acute */, + {0x00c2, 0xe5} /* capital letter a with circumflex */, + {0x00c3, 0xcc} /* capital letter a with tilde */, + {0x00c4, 0x80} /* capital letter a with diaeresis */, + {0x00c5, 0x81} /* capital letter a with ring above */, + {0x00c6, 0xae} /* capital letter ae */, + {0x00c7, 0x82} /* capital letter c with cedilla */, + {0x00c8, 0xe9} /* capital letter e with grave */, + {0x00c9, 0x83} /* capital letter e with acute */, + {0x00ca, 0xe6} /* capital letter e with circumflex */, + {0x00cb, 0xe8} /* capital letter e with diaeresis */, + {0x00cc, 0xed} /* capital letter i with grave */, + {0x00cd, 0xea} /* capital letter i with acute */, + {0x00ce, 0xeb} /* capital letter i with circumflex */, + {0x00cf, 0xec} /* capital letter i with diaeresis */, + {0x00d1, 0x84} /* capital letter n with tilde */, + {0x00d2, 0xf1} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xef} /* capital letter o with circumflex */, + {0x00d5, 0xcd} /* capital letter o with tilde */, + {0x00d6, 0x85} /* capital letter o with diaeresis */, + {0x00d8, 0xaf} /* capital letter o with stroke */, + {0x00d9, 0xf4} /* capital letter u with grave */, + {0x00da, 0xf2} /* capital letter u with acute */, + {0x00db, 0xf3} /* capital letter u with circumflex */, + {0x00dc, 0x86} /* capital letter u with diaeresis */, + {0x00df, 0xa7} /* small letter sharp s (german) */, + {0x00e0, 0x88} /* small letter a with grave */, + {0x00e1, 0x87} /* small letter a with acute */, + {0x00e2, 0x89} /* small letter a with circumflex */, + {0x00e3, 0x8b} /* small letter a with tilde */, + {0x00e4, 0x8a} /* small letter a with diaeresis */, + {0x00e5, 0x8c} /* small letter a with ring above */, + {0x00e6, 0xbe} /* small letter ae */, + {0x00e7, 0x8d} /* small letter c with cedilla */, + {0x00e8, 0x8f} /* small letter e with grave */, + {0x00e9, 0x8e} /* small letter e with acute */, + {0x00ea, 0x90} /* small letter e with circumflex */, + {0x00eb, 0x91} /* small letter e with diaeresis */, + {0x00ec, 0x93} /* small letter i with grave */, + {0x00ed, 0x92} /* small letter i with acute */, + {0x00ee, 0x94} /* small letter i with circumflex */, + {0x00ef, 0x95} /* small letter i with diaeresis */, + {0x00f1, 0x96} /* small letter n with tilde */, + {0x00f2, 0x98} /* small letter o with grave */, + {0x00f3, 0x97} /* small letter o with acute */, + {0x00f4, 0x99} /* small letter o with circumflex */, + {0x00f5, 0x9b} /* small letter o with tilde */, + {0x00f6, 0x9a} /* small letter o with diaeresis */, + {0x00f7, 0xd6} /* sign */, + {0x00f8, 0xbf} /* small letter o with stroke */, + {0x00f9, 0x9d} /* small letter u with grave */, + {0x00fa, 0x9c} /* small letter u with acute */, + {0x00fb, 0x9e} /* small letter u with circumflex */, + {0x00fc, 0x9f} /* small letter u with diaeresis */, + {0x00fe, 0xdf} /* small letter thorn (icelandic) */, + {0x00ff, 0xd8} /* small letter y with diaeresis */, + {0x0110, 0xdc} /* capital letter d with stroke */, + {0x0111, 0xdd} /* small letter d with stroke */, + {0x0131, 0xf5} /* small letter i dotless */, + {0x0152, 0xce} /* capital ligature oe */, + {0x0153, 0xcf} /* small ligature oe */, + {0x0178, 0xd9} /* capital letter y with diaeresis */, + {0x0192, 0xc4} /* minuscule latine f hameçon */, + {0x02c7, 0xff} /* caron */, + {0x02d8, 0xf9} /* breve */, + {0x02d9, 0xfa} /* above */, + {0x02da, 0xfb} /* above */, + {0x02db, 0xfe} /* ogonek */, + {0x02dd, 0xfd} /* acute accent */, + {0x0394, 0xc6} /* capital letter delta */, + {0x03a9, 0xbd} /* capital letter omega */, + {0x03c0, 0xb9} /* small letter pi */, + {0x2013, 0xd1} /* dash */, + {0x2014, 0xd0} /* dash */, + {0x2018, 0xd4} /* single quotation mark */, + {0x2019, 0xd5} /* single quotation mark */, + {0x201a, 0xe2} /* low-9 quotation mark */, + {0x201c, 0xd2} /* double quotation mark */, + {0x201d, 0xd3} /* double quotation mark */, + {0x201e, 0xe3} /* low-9 quotation mark */, + {0x2020, 0xa0} /* dagger */, + {0x2021, 0xe0} /* dagger */, + {0x2022, 0xa5} /* puce */, + {0x2026, 0xc9} /* horizontal ellipsis */, + {0x2030, 0xe4} /* mille sign */, + {0x2044, 0xda} /* slash */, + {0x2122, 0xaa} /* mark sign */, + {0x2202, 0xb6} /* differential */, + {0x220f, 0xb8} /* product */, + {0x2211, 0xb7} /* summation */, + {0x221a, 0xc3} /* root */, + {0x221e, 0xb0} /* infinity */, + {0x222b, 0xba} /* integral */, + {0x2248, 0xc5} /* equal to */, + {0x2260, 0xad} /* equal to */, + {0x2264, 0xb2} /* or equal to */, + {0x2265, 0xb3} /* or equal to */, + {0x25c6, 0xd7} /* diamond */, + {0xe01e, 0xf0} /* */ +}; + +/* +#define cet_ucs4_to_mac_is_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_mac_is_extra[cet_ucs4_to_mac_is_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_mac_is = /* defined in cet.h */ +{ + cet_cs_name_mac_is, /* name of character set */ + cet_cs_alias_mac_is, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_mac_is, /* char to UCS-4 value table */ + cet_ucs4_ofs_mac_is, /* first non standard character */ + cet_ucs4_cnt_mac_is, /* number of values in table */ + + cet_ucs4_to_mac_is_links, /* UCS-4 to char links */ + cet_ucs4_to_mac_is_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int mac_is_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2014, 0x2013, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x0110, 0x0111, 0x00de, 0x00fe, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; +*/ + +#endif diff --git a/cet/macintosh.h b/cet/macintosh.h new file mode 100644 index 000000000..f4f29735f --- /dev/null +++ b/cet/macintosh.h @@ -0,0 +1,250 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "macintosh" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef macintosh_h +#define macintosh_h + +#define cet_cs_name_macintosh "macintosh" + +const char *cet_cs_alias_macintosh[] = +{ + "macintosh", "csMacintosh", "mac", "MacRoman", + NULL +}; + +#define cet_ucs4_ofs_macintosh 128 +#define cet_ucs4_cnt_macintosh 128 + +const int cet_ucs4_map_macintosh[cet_ucs4_cnt_macintosh] = +{ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x2126, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; + +#define cet_ucs4_to_macintosh_ct 121 + +const cet_ucs4_link_t cet_ucs4_to_macintosh_links[cet_ucs4_to_macintosh_ct] = +{ + {0x00a0, 0xca} /* space */, + {0x00a1, 0xc1} /* exclamation mark */, + {0x00a4, 0xdb} /* sign */, + {0x00a5, 0xb4} /* sign */, + {0x00a7, 0xa4} /* sign */, + {0x00a8, 0xac} /* diaeresis */, + {0x00aa, 0xbb} /* ordinal indicator */, + {0x00ab, 0xc7} /* double angle quotation mark */, + {0x00ac, 0xc2} /* sign */, + {0x00ae, 0xa8} /* sign */, + {0x00af, 0xf8} /* macron */, + {0x00b0, 0xa1} /* sign */, + {0x00b4, 0xab} /* accent */, + {0x00b6, 0xa6} /* sign */, + {0x00b7, 0xe1} /* dot */, + {0x00b8, 0xfc} /* cedilla */, + {0x00ba, 0xbc} /* ordinal indicator */, + {0x00bb, 0xc8} /* double angle quotation mark */, + {0x00bf, 0xc0} /* question mark */, + {0x00c0, 0xcb} /* capital letter a with grave */, + {0x00c1, 0xe7} /* capital letter a with acute */, + {0x00c2, 0xe5} /* capital letter a with circumflex */, + {0x00c3, 0xcc} /* capital letter a with tilde */, + {0x00c4, 0x80} /* capital letter a with diaeresis */, + {0x00c5, 0x81} /* capital letter a with ring above */, + {0x00c6, 0xae} /* capital letter ae */, + {0x00c7, 0x82} /* capital letter c with cedilla */, + {0x00c8, 0xe9} /* capital letter e with grave */, + {0x00c9, 0x83} /* capital letter e with acute */, + {0x00ca, 0xe6} /* capital letter e with circumflex */, + {0x00cb, 0xe8} /* capital letter e with diaeresis */, + {0x00cc, 0xed} /* capital letter i with grave */, + {0x00cd, 0xea} /* capital letter i with acute */, + {0x00ce, 0xeb} /* capital letter i with circumflex */, + {0x00cf, 0xec} /* capital letter i with diaeresis */, + {0x00d1, 0x84} /* capital letter n with tilde */, + {0x00d2, 0xf1} /* capital letter o with grave */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xef} /* capital letter o with circumflex */, + {0x00d6, 0x85} /* capital letter o with diaeresis */, + {0x00d8, 0xaf} /* capital letter o with stroke */, + {0x00d9, 0xf4} /* capital letter u with grave */, + {0x00da, 0xf2} /* capital letter u with acute */, + {0x00db, 0xf3} /* capital letter u with circumflex */, + {0x00dc, 0x86} /* capital letter u with diaeresis */, + {0x00df, 0xa7} /* small letter sharp s (german) */, + {0x00e0, 0x88} /* small letter a with grave */, + {0x00e1, 0x87} /* small letter a with acute */, + {0x00e2, 0x89} /* small letter a with circumflex */, + {0x00e3, 0x8b} /* small letter a with tilde */, + {0x00e4, 0x8a} /* small letter a with diaeresis */, + {0x00e5, 0x8c} /* small letter a with ring above */, + {0x00e6, 0xbe} /* small letter ae */, + {0x00e7, 0x8d} /* small letter c with cedilla */, + {0x00e8, 0x8f} /* small letter e with grave */, + {0x00e9, 0x8e} /* small letter e with acute */, + {0x00ea, 0x90} /* small letter e with circumflex */, + {0x00eb, 0x91} /* small letter e with diaeresis */, + {0x00ec, 0x93} /* small letter i with grave */, + {0x00ed, 0x92} /* small letter i with acute */, + {0x00ee, 0x94} /* small letter i with circumflex */, + {0x00ef, 0x95} /* small letter i with diaeresis */, + {0x00f1, 0x96} /* small letter n with tilde */, + {0x00f2, 0x98} /* small letter o with grave */, + {0x00f3, 0x97} /* small letter o with acute */, + {0x00f4, 0x99} /* small letter o with circumflex */, + {0x00f5, 0x9b} /* small letter o with tilde */, + {0x00f6, 0x9a} /* small letter o with diaeresis */, + {0x00f7, 0xd6} /* sign */, + {0x00f8, 0xbf} /* small letter o with stroke */, + {0x00f9, 0x9d} /* small letter u with grave */, + {0x00fa, 0x9c} /* small letter u with acute */, + {0x00fb, 0x9e} /* small letter u with circumflex */, + {0x00fc, 0x9f} /* small letter u with diaeresis */, + {0x00ff, 0xd8} /* small letter y with diaeresis */, + {0x0131, 0xf5} /* small letter i dotless */, + {0x0152, 0xce} /* capital ligature oe */, + {0x0153, 0xcf} /* small ligature oe */, + {0x0178, 0xd9} /* capital letter y with diaeresis */, + {0x0192, 0xc4} /* minuscule latine f hameçon */, + {0x02c7, 0xff} /* caron */, + {0x02d8, 0xf9} /* breve */, + {0x02d9, 0xfa} /* above */, + {0x02da, 0xfb} /* above */, + {0x02db, 0xfe} /* ogonek */, + {0x02dd, 0xfd} /* acute accent */, + {0x0394, 0xc6} /* capital letter delta */, + {0x03a9, 0xbd} /* capital letter omega */, + {0x03c0, 0xb9} /* small letter pi */, + {0x2013, 0xd0} /* dash */, + {0x2014, 0xd1} /* dash */, + {0x2018, 0xd4} /* single quotation mark */, + {0x2019, 0xd5} /* single quotation mark */, + {0x201a, 0xe2} /* low-9 quotation mark */, + {0x201c, 0xd2} /* double quotation mark */, + {0x201d, 0xd3} /* double quotation mark */, + {0x201e, 0xe3} /* low-9 quotation mark */, + {0x2020, 0xa0} /* dagger */, + {0x2021, 0xe0} /* dagger */, + {0x2022, 0xa5} /* puce */, + {0x2026, 0xc9} /* horizontal ellipsis */, + {0x2030, 0xe4} /* mille sign */, + {0x2039, 0xdc} /* left-pointing angle quotation mark */, + {0x203a, 0xdd} /* right-pointing angle quotation mark */, + {0x2044, 0xda} /* slash */, + {0x2122, 0xaa} /* mark sign */, + {0x2126, 0xcd} /* sign */, + {0x2202, 0xb6} /* differential */, + {0x220f, 0xb8} /* product */, + {0x2211, 0xb7} /* summation */, + {0x221a, 0xc3} /* root */, + {0x221e, 0xb0} /* infinity */, + {0x222b, 0xba} /* integral */, + {0x2248, 0xc5} /* equal to */, + {0x2260, 0xad} /* equal to */, + {0x2264, 0xb2} /* or equal to */, + {0x2265, 0xb3} /* or equal to */, + {0x25ca, 0xd7} /* lozenge */, + {0xe01e, 0xf0} /* */, + {0xfb01, 0xde} /* small ligature fi */, + {0xfb02, 0xdf} /* small ligature fl */ +}; + +/* +#define cet_ucs4_to_macintosh_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_macintosh_extra[cet_ucs4_to_macintosh_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_macintosh = /* defined in cet.h */ +{ + cet_cs_name_macintosh, /* name of character set */ + cet_cs_alias_macintosh, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_macintosh, /* char to UCS-4 value table */ + cet_ucs4_ofs_macintosh, /* first non standard character */ + cet_ucs4_cnt_macintosh, /* number of values in table */ + + cet_ucs4_to_macintosh_links, /* UCS-4 to char links */ + cet_ucs4_to_macintosh_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int macintosh_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x2126, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xe01e, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, -1, -1, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7 +}; +*/ + +#endif diff --git a/cet/macintosh_ce.h b/cet/macintosh_ce.h new file mode 100644 index 000000000..4507de637 --- /dev/null +++ b/cet/macintosh_ce.h @@ -0,0 +1,254 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "macintosh_ce" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef macintosh_ce_h +#define macintosh_ce_h + +#define cet_cs_name_macintosh_ce "macintosh_ce" + +const char *cet_cs_alias_macintosh_ce[] = +{ + "macintosh_ce", "macce", NULL +}; + +#define cet_ucs4_ofs_macintosh_ce 128 +#define cet_ucs4_cnt_macintosh_ce 128 + +const int cet_ucs4_map_macintosh_ce[cet_ucs4_cnt_macintosh_ce] = +{ + 0x00c4, 0x0100, 0x0101, 0x00c9, 0x0104, 0x00d6, 0x00dc, 0x00e1, + 0x0105, 0x010c, 0x00e4, 0x010d, 0x0106, 0x0107, 0x00e9, 0x0179, + 0x017a, 0x010e, 0x00ed, 0x010f, 0x0112, 0x0113, 0x0116, 0x00f3, + 0x0117, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x011a, 0x011b, 0x00fc, + 0x2020, 0x00b0, 0x0118, 0x00a3, 0x00a7, 0x2219, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x0119, 0x00a8, 0x2260, 0x01f5, 0x012e, + 0x012f, 0x012a, 0x2264, 0x2265, 0x012b, 0x0136, 0x2202, 0x2211, + 0x0142, 0x013b, 0x013c, 0x013d, 0x013e, 0x0139, 0x013a, 0x0145, + 0x0146, 0x0143, 0x00ac, 0x221a, 0x0144, 0x0147, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x0148, 0x0150, 0x00d5, 0x0151, 0x014c, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x014d, 0x0154, 0x0155, 0x0158, 0x2039, 0x203a, 0x0159, 0x0156, + 0x0157, 0x0160, 0x201a, 0x201e, 0x0161, 0x015a, 0x015b, 0x00c1, + 0x0164, 0x0165, 0x00cd, 0x017d, 0x017e, 0x016a, 0x00d3, 0x00d4, + 0x016b, 0x016e, 0x00da, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, + 0x00dd, 0x00fd, 0x0137, 0x017b, 0x0141, 0x017c, 0x0122, 0x02c7 +}; + +#define cet_ucs4_to_macintosh_ce_ct 126 + +const cet_ucs4_link_t cet_ucs4_to_macintosh_ce_links[cet_ucs4_to_macintosh_ce_ct] = +{ + {0x00a0, 0xca} /* space */, + {0x00a7, 0xa4} /* sign */, + {0x00a8, 0xac} /* diaeresis */, + {0x00ab, 0xc7} /* double angle quotation mark */, + {0x00ac, 0xc2} /* sign */, + {0x00ae, 0xa8} /* sign */, + {0x00b0, 0xa1} /* sign */, + {0x00b6, 0xa6} /* sign */, + {0x00bb, 0xc8} /* double angle quotation mark */, + {0x00c1, 0xe7} /* capital letter a with acute */, + {0x00c4, 0x80} /* capital letter a with diaeresis */, + {0x00c9, 0x83} /* capital letter e with acute */, + {0x00cd, 0xea} /* capital letter i with acute */, + {0x00d3, 0xee} /* capital letter o with acute */, + {0x00d4, 0xef} /* capital letter o with circumflex */, + {0x00d5, 0xcd} /* capital letter o with tilde */, + {0x00d6, 0x85} /* capital letter o with diaeresis */, + {0x00da, 0xf2} /* capital letter u with acute */, + {0x00dc, 0x86} /* capital letter u with diaeresis */, + {0x00dd, 0xf8} /* capital letter y with acute */, + {0x00df, 0xa7} /* small letter sharp s (german) */, + {0x00e1, 0x87} /* small letter a with acute */, + {0x00e4, 0x8a} /* small letter a with diaeresis */, + {0x00e9, 0x8e} /* small letter e with acute */, + {0x00ed, 0x92} /* small letter i with acute */, + {0x00f3, 0x97} /* small letter o with acute */, + {0x00f4, 0x99} /* small letter o with circumflex */, + {0x00f5, 0x9b} /* small letter o with tilde */, + {0x00f6, 0x9a} /* small letter o with diaeresis */, + {0x00f7, 0xd6} /* sign */, + {0x00fa, 0x9c} /* small letter u with acute */, + {0x00fc, 0x9f} /* small letter u with diaeresis */, + {0x00fd, 0xf9} /* small letter y with acute */, + {0x0100, 0x81} /* capital letter a with macron */, + {0x0101, 0x82} /* small letter a with macron */, + {0x0104, 0x84} /* capital letter a with ogonek */, + {0x0105, 0x88} /* small letter a with ogonek */, + {0x0106, 0x8c} /* capital letter c with acute */, + {0x0107, 0x8d} /* small letter c with acute */, + {0x010c, 0x89} /* capital letter c with caron */, + {0x010d, 0x8b} /* small letter c with caron */, + {0x010e, 0x91} /* capital letter d with caron */, + {0x010f, 0x93} /* small letter d with caron */, + {0x0112, 0x94} /* capital letter e with macron */, + {0x0113, 0x95} /* small letter e with macron */, + {0x0116, 0x96} /* capital letter e with dot above */, + {0x0117, 0x98} /* small letter e with dot above */, + {0x0118, 0xa2} /* capital letter e with ogonek */, + {0x0119, 0xab} /* small letter e with ogonek */, + {0x011a, 0x9d} /* capital letter e with caron */, + {0x011b, 0x9e} /* small letter e with caron */, + {0x0122, 0xfe} /* capital letter g with cedilla */, + {0x012a, 0xb1} /* capital letter i with macron */, + {0x012b, 0xb4} /* small letter i with macron */, + {0x012e, 0xaf} /* capital letter i with ogonek */, + {0x012f, 0xb0} /* small letter i with ogonek */, + {0x0136, 0xb5} /* capital letter k with cedilla */, + {0x0137, 0xfa} /* small letter k with cedilla */, + {0x0139, 0xbd} /* capital letter l with acute */, + {0x013a, 0xbe} /* small letter l with acute */, + {0x013b, 0xb9} /* capital letter l with cedilla */, + {0x013c, 0xba} /* small letter l with cedilla */, + {0x013d, 0xbb} /* capital letter l with caron */, + {0x013e, 0xbc} /* small letter l with caron */, + {0x0141, 0xfc} /* capital letter l with stroke */, + {0x0142, 0xb8} /* small letter l with stroke */, + {0x0143, 0xc1} /* capital letter n with acute */, + {0x0144, 0xc4} /* small letter n with acute */, + {0x0145, 0xbf} /* capital letter n with cedilla */, + {0x0146, 0xc0} /* small letter n with cedilla */, + {0x0147, 0xc5} /* capital letter n with caron */, + {0x0148, 0xcb} /* small letter n with caron */, + {0x014c, 0xcf} /* capital letter o with macron */, + {0x014d, 0xd8} /* small letter o with macron */, + {0x0150, 0xcc} /* capital letter o with double acute */, + {0x0151, 0xce} /* small letter o with double acute */, + {0x0154, 0xd9} /* capital letter r with acute */, + {0x0155, 0xda} /* small letter r with acute */, + {0x0156, 0xdf} /* capital letter r with cedilla */, + {0x0157, 0xe0} /* small letter r with cedilla */, + {0x0158, 0xdb} /* capital letter r with caron */, + {0x0159, 0xde} /* small letter r with caron */, + {0x015a, 0xe5} /* capital letter s with acute */, + {0x015b, 0xe6} /* small letter s with acute */, + {0x0160, 0xe1} /* capital letter s with caron */, + {0x0161, 0xe4} /* small letter s with caron */, + {0x0164, 0xe8} /* capital letter t with caron */, + {0x0165, 0xe9} /* small letter t with caron */, + {0x016a, 0xed} /* capital letter u with macron */, + {0x016b, 0xf0} /* small letter u with macron */, + {0x016e, 0xf1} /* capital letter u with ring above */, + {0x016f, 0xf3} /* small letter u with ring above */, + {0x0170, 0xf4} /* capital letter u with double acute */, + {0x0171, 0xf5} /* small letter u with double acute */, + {0x0172, 0xf6} /* capital letter u with ogonek */, + {0x0173, 0xf7} /* small letter u with ogonek */, + {0x0179, 0x8f} /* capital letter z with acute */, + {0x017a, 0x90} /* small letter z with acute */, + {0x017b, 0xfb} /* capital letter z with dot above */, + {0x017c, 0xfd} /* small letter z with dot above */, + {0x017d, 0xeb} /* capital letter z with caron */, + {0x017e, 0xec} /* small letter z with caron */, + {0x01f5, 0xae} /* small letter g with acute */, + {0x02c7, 0xff} /* caron */, + {0x0394, 0xc6} /* capital letter delta */, + {0x2013, 0xd0} /* dash */, + {0x2014, 0xd1} /* dash */, + {0x2018, 0xd4} /* single quotation mark */, + {0x2019, 0xd5} /* single quotation mark */, + {0x201a, 0xe2} /* low-9 quotation mark */, + {0x201c, 0xd2} /* double quotation mark */, + {0x201d, 0xd3} /* double quotation mark */, + {0x201e, 0xe3} /* low-9 quotation mark */, + {0x2020, 0xa0} /* dagger */, + {0x2026, 0xc9} /* horizontal ellipsis */, + {0x2039, 0xdc} /* left-pointing angle quotation mark */, + {0x203a, 0xdd} /* right-pointing angle quotation mark */, + {0x2122, 0xaa} /* mark sign */, + {0x2202, 0xb6} /* differential */, + {0x2211, 0xb7} /* summation */, + {0x2219, 0xa5} /* operator */, + {0x221a, 0xc3} /* root */, + {0x2260, 0xad} /* equal to */, + {0x2264, 0xb2} /* or equal to */, + {0x2265, 0xb3} /* or equal to */, + {0x25c6, 0xd7} /* diamond */ +}; + +/* +#define cet_ucs4_to_macintosh_ce_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_macintosh_ce_extra[cet_ucs4_to_macintosh_ce_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_macintosh_ce = /* defined in cet.h */ +{ + cet_cs_name_macintosh_ce, /* name of character set */ + cet_cs_alias_macintosh_ce, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_macintosh_ce, /* char to UCS-4 value table */ + cet_ucs4_ofs_macintosh_ce, /* first non standard character */ + cet_ucs4_cnt_macintosh_ce, /* number of values in table */ + + cet_ucs4_to_macintosh_ce_links, /* UCS-4 to char links */ + cet_ucs4_to_macintosh_ce_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int macintosh_ce_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c4, 0x0100, 0x0101, 0x00c9, 0x0104, 0x00d6, 0x00dc, 0x00e1, + 0x0105, 0x010c, 0x00e4, 0x010d, 0x0106, 0x0107, 0x00e9, 0x0179, + 0x017a, 0x010e, 0x00ed, 0x010f, 0x0112, 0x0113, 0x0116, 0x00f3, + 0x0117, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x011a, 0x011b, 0x00fc, + 0x2020, 0x00b0, 0x0118, 0x00a3, 0x00a7, 0x2219, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x0119, 0x00a8, 0x2260, 0x01f5, 0x012e, + 0x012f, 0x012a, 0x2264, 0x2265, 0x012b, 0x0136, 0x2202, 0x2211, + 0x0142, 0x013b, 0x013c, 0x013d, 0x013e, 0x0139, 0x013a, 0x0145, + 0x0146, 0x0143, 0x00ac, 0x221a, 0x0144, 0x0147, 0x0394, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x0148, 0x0150, 0x00d5, 0x0151, 0x014c, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25c6, + 0x014d, 0x0154, 0x0155, 0x0158, 0x2039, 0x203a, 0x0159, 0x0156, + 0x0157, 0x0160, 0x201a, 0x201e, 0x0161, 0x015a, 0x015b, 0x00c1, + 0x0164, 0x0165, 0x00cd, 0x017d, 0x017e, 0x016a, 0x00d3, 0x00d4, + 0x016b, 0x016e, 0x00da, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, + 0x00dd, 0x00fd, 0x0137, 0x017b, 0x0141, 0x017c, 0x0122, 0x02c7 +}; +*/ + +#endif diff --git a/cet/msz_7795_3.h b/cet/msz_7795_3.h new file mode 100644 index 000000000..0034a41bf --- /dev/null +++ b/cet/msz_7795_3.h @@ -0,0 +1,135 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "MSZ_7795.3" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef msz_7795_3_h +#define msz_7795_3_h + +#define cet_cs_name_msz_7795_3 "MSZ_7795.3" + +const char *cet_cs_alias_msz_7795_3[] = +{ + "MSZ_7795.3", "hu", "ISO646-HU", "iso-ir-86", + NULL +}; + +#define cet_ucs4_ofs_msz_7795_3 36 +#define cet_ucs4_cnt_msz_7795_3 92 + +const int cet_ucs4_map_msz_7795_3[cet_ucs4_cnt_msz_7795_3] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x00c1, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c9, + 0x00d6, 0x00dc, 0x005e, 0x005f, 0x00e1, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e9, + 0x00f6, 0x00fc, 0x02dd, 0x007f +}; + +#define cet_ucs4_to_msz_7795_3_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_msz_7795_3_links[cet_ucs4_to_msz_7795_3_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x00c1, 0x40} /* capital letter a with acute */, + {0x00c9, 0x5b} /* capital letter e with acute */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00dc, 0x5d} /* capital letter u with diaeresis */, + {0x00e1, 0x60} /* small letter a with acute */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x00fc, 0x7d} /* small letter u with diaeresis */, + {0x02dd, 0x7e} /* acute accent */ +}; + +/* +#define cet_ucs4_to_msz_7795_3_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_msz_7795_3_extra[cet_ucs4_to_msz_7795_3_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_msz_7795_3 = /* defined in cet.h */ +{ + cet_cs_name_msz_7795_3, /* name of character set */ + cet_cs_alias_msz_7795_3, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_msz_7795_3, /* char to UCS-4 value table */ + cet_ucs4_ofs_msz_7795_3, /* first non standard character */ + cet_ucs4_cnt_msz_7795_3, /* number of values in table */ + + cet_ucs4_to_msz_7795_3_links, /* UCS-4 to char links */ + cet_ucs4_to_msz_7795_3_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int msz_7795_3_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00c1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c9, 0x00d6, 0x00dc, 0x005e, 0x005f, + 0x00e1, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f6, 0x00fc, 0x02dd, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nats_dano.h b/cet/nats_dano.h new file mode 100644 index 000000000..beb3433a4 --- /dev/null +++ b/cet/nats_dano.h @@ -0,0 +1,136 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NATS-DANO" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nats_dano_h +#define nats_dano_h + +#define cet_cs_name_nats_dano "NATS-DANO" + +const char *cet_cs_alias_nats_dano[] = +{ + "NATS-DANO", "iso-ir-9-1", NULL +}; + +#define cet_ucs4_ofs_nats_dano 34 +#define cet_ucs4_cnt_nats_dano 94 + +const int cet_ucs4_map_nats_dano[cet_ucs4_cnt_nats_dano] = +{ + 0x00ab, 0x00bb, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, + 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0xe018, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, + 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, + 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x25a0, 0x005f, 0xe019, 0x0061, + 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x2013, 0x007f +}; + +#define cet_ucs4_to_nats_dano_ct 12 + +const cet_ucs4_link_t cet_ucs4_to_nats_dano_links[cet_ucs4_to_nats_dano_ct] = +{ + {0x00ab, 0x22} /* double angle quotation mark */, + {0x00bb, 0x23} /* double angle quotation mark */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */, + {0x2013, 0x7e} /* dash */, + {0x25a0, 0x5e} /* square */, + {0xe018, 0x40} /* space a (iso-ir-8-1 064) */, + {0xe019, 0x60} /* space b (iso-ir-8-1 096) */ +}; + +/* +#define cet_ucs4_to_nats_dano_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nats_dano_extra[cet_ucs4_to_nats_dano_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nats_dano = /* defined in cet.h */ +{ + cet_cs_name_nats_dano, /* name of character set */ + cet_cs_alias_nats_dano, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nats_dano, /* char to UCS-4 value table */ + cet_ucs4_ofs_nats_dano, /* first non standard character */ + cet_ucs4_cnt_nats_dano, /* number of values in table */ + + cet_ucs4_to_nats_dano_links, /* UCS-4 to char links */ + cet_ucs4_to_nats_dano_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nats_dano_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x00ab, 0x00bb, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0xe018, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x25a0, 0x005f, + 0xe019, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x2013, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nats_sefi.h b/cet/nats_sefi.h new file mode 100644 index 000000000..93c0713ec --- /dev/null +++ b/cet/nats_sefi.h @@ -0,0 +1,130 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NATS-SEFI" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nats_sefi_h +#define nats_sefi_h + +#define cet_cs_name_nats_sefi "NATS-SEFI" + +const char *cet_cs_alias_nats_sefi[] = +{ + "NATS-SEFI", "iso-ir-8-1", NULL +}; + +#define cet_ucs4_ofs_nats_sefi 64 +#define cet_ucs4_cnt_nats_sefi 64 + +const int cet_ucs4_map_nats_sefi[cet_ucs4_cnt_nats_sefi] = +{ + 0xe018, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x25a0, 0x005f, + 0xe019, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x2013, 0x007f +}; + +#define cet_ucs4_to_nats_sefi_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_nats_sefi_links[cet_ucs4_to_nats_sefi_ct] = +{ + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x2013, 0x7e} /* dash */, + {0x25a0, 0x5e} /* square */, + {0xe018, 0x40} /* space a (iso-ir-8-1 064) */, + {0xe019, 0x60} /* space b (iso-ir-8-1 096) */ +}; + +/* +#define cet_ucs4_to_nats_sefi_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nats_sefi_extra[cet_ucs4_to_nats_sefi_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nats_sefi = /* defined in cet.h */ +{ + cet_cs_name_nats_sefi, /* name of character set */ + cet_cs_alias_nats_sefi, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nats_sefi, /* char to UCS-4 value table */ + cet_ucs4_ofs_nats_sefi, /* first non standard character */ + cet_ucs4_cnt_nats_sefi, /* number of values in table */ + + cet_ucs4_to_nats_sefi_links, /* UCS-4 to char links */ + cet_ucs4_to_nats_sefi_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nats_sefi_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0xe018, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x25a0, 0x005f, + 0xe019, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x2013, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nc_nc00_10.h b/cet/nc_nc00_10.h new file mode 100644 index 000000000..256cc493c --- /dev/null +++ b/cet/nc_nc00_10.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NC_NC00-10" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nc_nc00_10_h +#define nc_nc00_10_h + +#define cet_cs_name_nc_nc00_10 "NC_NC00-10" + +const char *cet_cs_alias_nc_nc00_10[] = +{ + "NC_NC00-10", "cuba", "ISO646-CU", "iso-ir-151", + "NC_NC00-10:81", NULL +}; + +#define cet_ucs4_ofs_nc_nc00_10 36 +#define cet_ucs4_cnt_nc_nc00_10 92 + +const int cet_ucs4_map_nc_nc00_10[cet_ucs4_cnt_nc_nc00_10] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00a1, + 0x00d1, 0x005d, 0x00bf, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00b4, + 0x00f1, 0x005b, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_nc_nc00_10_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_nc_nc00_10_links[cet_ucs4_to_nc_nc00_10_ct] = +{ + {0x005b, 0x7d} /* square bracket */, + {0x00a1, 0x5b} /* exclamation mark */, + {0x00a4, 0x24} /* sign */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b4, 0x7b} /* accent */, + {0x00bf, 0x5e} /* question mark */, + {0x00d1, 0x5c} /* capital letter n with tilde */, + {0x00f1, 0x7c} /* small letter n with tilde */ +}; + +/* +#define cet_ucs4_to_nc_nc00_10_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nc_nc00_10_extra[cet_ucs4_to_nc_nc00_10_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nc_nc00_10 = /* defined in cet.h */ +{ + cet_cs_name_nc_nc00_10, /* name of character set */ + cet_cs_alias_nc_nc00_10, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nc_nc00_10, /* char to UCS-4 value table */ + cet_ucs4_ofs_nc_nc00_10, /* first non standard character */ + cet_ucs4_cnt_nc_nc00_10, /* number of values in table */ + + cet_ucs4_to_nc_nc00_10_links, /* UCS-4 to char links */ + cet_ucs4_to_nc_nc00_10_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nc_nc00_10_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00a1, 0x00d1, 0x005d, 0x00bf, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00b4, 0x00f1, 0x005b, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nextstep.h b/cet/nextstep.h new file mode 100644 index 000000000..f4e4a5d3a --- /dev/null +++ b/cet/nextstep.h @@ -0,0 +1,240 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NeXTSTEP" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nextstep_h +#define nextstep_h + +#define cet_cs_name_nextstep "NeXTSTEP" + +const char *cet_cs_alias_nextstep[] = +{ + "NeXTSTEP", "next", NULL +}; + +#define cet_ucs4_ofs_nextstep 128 +#define cet_ucs4_cnt_nextstep 126 + +const int cet_ucs4_map_nextstep[cet_ucs4_cnt_nextstep] = +{ + 0x00a0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d9, + 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00b5, 0x00d7, 0x00f7, + 0x00a9, 0x00a1, 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, + 0x00a4, -1, 0x201c, 0x00ab, -1, -1, 0xfb01, 0xfb02, + 0x00ae, 0x2013, 0x2020, 0x2021, 0x00b7, 0x00a6, 0x00b6, 0x2022, + -1, -1, 0x201d, 0x00bb, 0x2026, 0x2030, 0x00ac, 0x00bf, + 0x00b9, 0x02cb, 0x00b4, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, + 0x00a8, 0x00b2, 0x02da, 0x00b8, 0x00b3, 0x02dd, 0x02db, 0x02c7, + 0x2014, 0x00b1, 0x00bc, 0x00bd, 0x00be, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ec, 0x00c6, 0x00ed, 0x00aa, 0x00ee, 0x00ef, 0x00f0, 0x00f1, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00f2, 0x00f3, 0x00f4, 0x00f5, + 0x00f6, 0x00e6, 0x00f9, 0x00fa, 0x00fb, 0x0131, 0x00fc, 0x00fd, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x00ff +}; + +#define cet_ucs4_to_nextstep_ct 112 + +const cet_ucs4_link_t cet_ucs4_to_nextstep_links[cet_ucs4_to_nextstep_ct] = +{ + {0x00a0, 0x80} /* space */, + {0x00a4, 0xa8} /* sign */, + {0x00a6, 0xb5} /* bar */, + {0x00a8, 0xc8} /* diaeresis */, + {0x00a9, 0xa0} /* sign */, + {0x00aa, 0xe3} /* ordinal indicator */, + {0x00ac, 0xbe} /* sign */, + {0x00ae, 0xb0} /* sign */, + {0x00af, 0xc5} /* macron */, + {0x00b1, 0xd1} /* sign */, + {0x00b2, 0xc9} /* two */, + {0x00b3, 0xcc} /* three */, + {0x00b4, 0xc2} /* accent */, + {0x00b5, 0x9d} /* sign */, + {0x00b7, 0xb4} /* dot */, + {0x00b8, 0xcb} /* cedilla */, + {0x00b9, 0xc0} /* one */, + {0x00ba, 0xeb} /* ordinal indicator */, + {0x00bc, 0xd2} /* fraction one quarter */, + {0x00bd, 0xd3} /* fraction one half */, + {0x00be, 0xd4} /* fraction three quarters */, + {0x00c0, 0x81} /* capital letter a with grave */, + {0x00c1, 0x82} /* capital letter a with acute */, + {0x00c2, 0x83} /* capital letter a with circumflex */, + {0x00c3, 0x84} /* capital letter a with tilde */, + {0x00c4, 0x85} /* capital letter a with diaeresis */, + {0x00c5, 0x86} /* capital letter a with ring above */, + {0x00c6, 0xe1} /* capital letter ae */, + {0x00c7, 0x87} /* capital letter c with cedilla */, + {0x00c8, 0x88} /* capital letter e with grave */, + {0x00c9, 0x89} /* capital letter e with acute */, + {0x00ca, 0x8a} /* capital letter e with circumflex */, + {0x00cb, 0x8b} /* capital letter e with diaeresis */, + {0x00cc, 0x8c} /* capital letter i with grave */, + {0x00cd, 0x8d} /* capital letter i with acute */, + {0x00ce, 0x8e} /* capital letter i with circumflex */, + {0x00cf, 0x8f} /* capital letter i with diaeresis */, + {0x00d0, 0x90} /* capital letter eth (icelandic) */, + {0x00d1, 0x91} /* capital letter n with tilde */, + {0x00d2, 0x92} /* capital letter o with grave */, + {0x00d3, 0x93} /* capital letter o with acute */, + {0x00d4, 0x94} /* capital letter o with circumflex */, + {0x00d5, 0x95} /* capital letter o with tilde */, + {0x00d6, 0x96} /* capital letter o with diaeresis */, + {0x00d7, 0x9e} /* sign */, + {0x00d8, 0xe9} /* capital letter o with stroke */, + {0x00d9, 0x97} /* capital letter u with grave */, + {0x00da, 0x98} /* capital letter u with acute */, + {0x00db, 0x99} /* capital letter u with circumflex */, + {0x00dc, 0x9a} /* capital letter u with diaeresis */, + {0x00dd, 0x9b} /* capital letter y with acute */, + {0x00de, 0x9c} /* capital letter thorn (icelandic) */, + {0x00df, 0xfb} /* small letter sharp s (german) */, + {0x00e0, 0xd5} /* small letter a with grave */, + {0x00e1, 0xd6} /* small letter a with acute */, + {0x00e2, 0xd7} /* small letter a with circumflex */, + {0x00e3, 0xd8} /* small letter a with tilde */, + {0x00e4, 0xd9} /* small letter a with diaeresis */, + {0x00e5, 0xda} /* small letter a with ring above */, + {0x00e6, 0xf1} /* small letter ae */, + {0x00e7, 0xdb} /* small letter c with cedilla */, + {0x00e8, 0xdc} /* small letter e with grave */, + {0x00e9, 0xdd} /* small letter e with acute */, + {0x00ea, 0xde} /* small letter e with circumflex */, + {0x00eb, 0xdf} /* small letter e with diaeresis */, + {0x00ec, 0xe0} /* small letter i with grave */, + {0x00ed, 0xe2} /* small letter i with acute */, + {0x00ee, 0xe4} /* small letter i with circumflex */, + {0x00ef, 0xe5} /* small letter i with diaeresis */, + {0x00f0, 0xe6} /* small letter eth (icelandic) */, + {0x00f1, 0xe7} /* small letter n with tilde */, + {0x00f2, 0xec} /* small letter o with grave */, + {0x00f3, 0xed} /* small letter o with acute */, + {0x00f4, 0xee} /* small letter o with circumflex */, + {0x00f5, 0xef} /* small letter o with tilde */, + {0x00f6, 0xf0} /* small letter o with diaeresis */, + {0x00f7, 0x9f} /* sign */, + {0x00f8, 0xf9} /* small letter o with stroke */, + {0x00f9, 0xf2} /* small letter u with grave */, + {0x00fa, 0xf3} /* small letter u with acute */, + {0x00fb, 0xf4} /* small letter u with circumflex */, + {0x00fc, 0xf6} /* small letter u with diaeresis */, + {0x00fd, 0xf7} /* small letter y with acute */, + {0x00fe, 0xfc} /* small letter thorn (icelandic) */, + {0x00ff, 0xfd} /* small letter y with diaeresis */, + {0x0131, 0xf5} /* small letter i dotless */, + {0x0141, 0xe8} /* capital letter l with stroke */, + {0x0142, 0xf8} /* small letter l with stroke */, + {0x0152, 0xea} /* capital ligature oe */, + {0x0153, 0xfa} /* small ligature oe */, + {0x0192, 0xa6} /* minuscule latine f hameçon */, + {0x02c6, 0xc3} /* modificative accent circonflexe */, + {0x02c7, 0xcf} /* caron */, + {0x02cb, 0xc1} /* modificative accent grave */, + {0x02d8, 0xc6} /* breve */, + {0x02d9, 0xc7} /* above */, + {0x02da, 0xca} /* above */, + {0x02db, 0xce} /* ogonek */, + {0x02dc, 0xc4} /* tilde */, + {0x02dd, 0xcd} /* acute accent */, + {0x2013, 0xb1} /* dash */, + {0x2014, 0xd0} /* dash */, + {0x201c, 0xaa} /* double quotation mark */, + {0x201d, 0xba} /* double quotation mark */, + {0x2020, 0xb2} /* dagger */, + {0x2021, 0xb3} /* dagger */, + {0x2022, 0xb7} /* puce */, + {0x2026, 0xbc} /* horizontal ellipsis */, + {0x2030, 0xbd} /* mille sign */, + {0x2044, 0xa4} /* slash */, + {0xfb01, 0xae} /* small ligature fi */, + {0xfb02, 0xaf} /* small ligature fl */ +}; + +/* +#define cet_ucs4_to_nextstep_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nextstep_extra[cet_ucs4_to_nextstep_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nextstep = /* defined in cet.h */ +{ + cet_cs_name_nextstep, /* name of character set */ + cet_cs_alias_nextstep, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nextstep, /* char to UCS-4 value table */ + cet_ucs4_ofs_nextstep, /* first non standard character */ + cet_ucs4_cnt_nextstep, /* number of values in table */ + + cet_ucs4_to_nextstep_links, /* UCS-4 to char links */ + cet_ucs4_to_nextstep_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nextstep_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00a0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d9, + 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00b5, 0x00d7, 0x00f7, + 0x00a9, 0x00a1, 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, + 0x00a4, -1, 0x201c, 0x00ab, -1, -1, 0xfb01, 0xfb02, + 0x00ae, 0x2013, 0x2020, 0x2021, 0x00b7, 0x00a6, 0x00b6, 0x2022, + -1, -1, 0x201d, 0x00bb, 0x2026, 0x2030, 0x00ac, 0x00bf, + 0x00b9, 0x02cb, 0x00b4, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, + 0x00a8, 0x00b2, 0x02da, 0x00b8, 0x00b3, 0x02dd, 0x02db, 0x02c7, + 0x2014, 0x00b1, 0x00bc, 0x00bd, 0x00be, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + 0x00ec, 0x00c6, 0x00ed, 0x00aa, 0x00ee, 0x00ef, 0x00f0, 0x00f1, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00f2, 0x00f3, 0x00f4, 0x00f5, + 0x00f6, 0x00e6, 0x00f9, 0x00fa, 0x00fb, 0x0131, 0x00fc, 0x00fd, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x00ff, -1, -1 +}; +*/ + +#endif diff --git a/cet/nf_z_62_010.h b/cet/nf_z_62_010.h new file mode 100644 index 000000000..97a0cea8f --- /dev/null +++ b/cet/nf_z_62_010.h @@ -0,0 +1,135 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NF_Z_62-010" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nf_z_62_010_h +#define nf_z_62_010_h + +#define cet_cs_name_nf_z_62_010 "NF_Z_62-010" + +const char *cet_cs_alias_nf_z_62_010[] = +{ + "NF_Z_62-010", "fr", "ISO646-FR", "iso-ir-69", + NULL +}; + +#define cet_ucs4_ofs_nf_z_62_010 35 +#define cet_ucs4_cnt_nf_z_62_010 93 + +const int cet_ucs4_map_nf_z_62_010[cet_ucs4_cnt_nf_z_62_010] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00e0, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, 0x00b5, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_nf_z_62_010_ct 10 + +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010_links[cet_ucs4_to_nf_z_62_010_ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x5d} /* sign */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b0, 0x5b} /* sign */, + {0x00b5, 0x60} /* sign */, + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00f9, 0x7c} /* small letter u with grave */ +}; + +/* +#define cet_ucs4_to_nf_z_62_010_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010_extra[cet_ucs4_to_nf_z_62_010_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nf_z_62_010 = /* defined in cet.h */ +{ + cet_cs_name_nf_z_62_010, /* name of character set */ + cet_cs_alias_nf_z_62_010, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nf_z_62_010, /* char to UCS-4 value table */ + cet_ucs4_ofs_nf_z_62_010, /* first non standard character */ + cet_ucs4_cnt_nf_z_62_010, /* number of values in table */ + + cet_ucs4_to_nf_z_62_010_links, /* UCS-4 to char links */ + cet_ucs4_to_nf_z_62_010_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nf_z_62_010_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, + 0x00b5, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/nf_z_62_010__1973_.h b/cet/nf_z_62_010__1973_.h new file mode 100644 index 000000000..b1b027cad --- /dev/null +++ b/cet/nf_z_62_010__1973_.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NF_Z_62-010_(1973)" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef nf_z_62_010__1973__h +#define nf_z_62_010__1973__h + +#define cet_cs_name_nf_z_62_010__1973_ "NF_Z_62-010_(1973)" + +const char *cet_cs_alias_nf_z_62_010__1973_[] = +{ + "NF_Z_62-010_(1973)", "ISO646-FR1", "iso-ir-25", NULL +}; + +#define cet_ucs4_ofs_nf_z_62_010__1973_ 35 +#define cet_ucs4_cnt_nf_z_62_010__1973_ 93 + +const int cet_ucs4_map_nf_z_62_010__1973_[cet_ucs4_cnt_nf_z_62_010__1973_] = +{ + 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x00e0, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f +}; + +#define cet_ucs4_to_nf_z_62_010__1973__ct 9 + +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010__1973__links[cet_ucs4_to_nf_z_62_010__1973__ct] = +{ + {0x00a3, 0x23} /* sign */, + {0x00a7, 0x5d} /* sign */, + {0x00a8, 0x7e} /* diaeresis */, + {0x00b0, 0x5b} /* sign */, + {0x00e0, 0x40} /* small letter a with grave */, + {0x00e7, 0x5c} /* small letter c with cedilla */, + {0x00e8, 0x7d} /* small letter e with grave */, + {0x00e9, 0x7b} /* small letter e with acute */, + {0x00f9, 0x7c} /* small letter u with grave */ +}; + +/* +#define cet_ucs4_to_nf_z_62_010__1973__extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_nf_z_62_010__1973__extra[cet_ucs4_to_nf_z_62_010__1973__extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_nf_z_62_010__1973_ = /* defined in cet.h */ +{ + cet_cs_name_nf_z_62_010__1973_, /* name of character set */ + cet_cs_alias_nf_z_62_010__1973_, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_nf_z_62_010__1973_, /* char to UCS-4 value table */ + cet_ucs4_ofs_nf_z_62_010__1973_, /* first non standard character */ + cet_ucs4_cnt_nf_z_62_010__1973_, /* number of values in table */ + + cet_ucs4_to_nf_z_62_010__1973__links, /* UCS-4 to char links */ + cet_ucs4_to_nf_z_62_010__1973__ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int nf_z_62_010__1973__ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a3, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00e0, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e9, 0x00f9, 0x00e8, 0x00a8, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ns_4551_1.h b/cet/ns_4551_1.h new file mode 100644 index 000000000..edad059e4 --- /dev/null +++ b/cet/ns_4551_1.h @@ -0,0 +1,125 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NS_4551-1" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ns_4551_1_h +#define ns_4551_1_h + +#define cet_cs_name_ns_4551_1 "NS_4551-1" + +const char *cet_cs_alias_ns_4551_1[] = +{ + "NS_4551-1", "ISO646-NO", "iso-ir-60", "no", + NULL +}; + +#define cet_ucs4_ofs_ns_4551_1 91 +#define cet_ucs4_cnt_ns_4551_1 37 + +const int cet_ucs4_map_ns_4551_1[cet_ucs4_cnt_ns_4551_1] = +{ + 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e6, 0x00f8, 0x00e5, 0x203e, 0x007f +}; + +#define cet_ucs4_to_ns_4551_1_ct 7 + +const cet_ucs4_link_t cet_ucs4_to_ns_4551_1_links[cet_ucs4_to_ns_4551_1_ct] = +{ + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_ns_4551_1_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ns_4551_1_extra[cet_ucs4_to_ns_4551_1_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ns_4551_1 = /* defined in cet.h */ +{ + cet_cs_name_ns_4551_1, /* name of character set */ + cet_cs_alias_ns_4551_1, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ns_4551_1, /* char to UCS-4 value table */ + cet_ucs4_ofs_ns_4551_1, /* first non standard character */ + cet_ucs4_cnt_ns_4551_1, /* number of values in table */ + + cet_ucs4_to_ns_4551_1_links, /* UCS-4 to char links */ + cet_ucs4_to_ns_4551_1_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ns_4551_1_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/ns_4551_2.h b/cet/ns_4551_2.h new file mode 100644 index 000000000..9b21e20e2 --- /dev/null +++ b/cet/ns_4551_2.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "NS_4551-2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef ns_4551_2_h +#define ns_4551_2_h + +#define cet_cs_name_ns_4551_2 "NS_4551-2" + +const char *cet_cs_alias_ns_4551_2[] = +{ + "NS_4551-2", "ISO646-NO2", "iso-ir-61", "no2", + NULL +}; + +#define cet_ucs4_ofs_ns_4551_2 35 +#define cet_ucs4_cnt_ns_4551_2 93 + +const int cet_ucs4_map_ns_4551_2[cet_ucs4_cnt_ns_4551_2] = +{ + 0x00a7, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, + 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, + 0x00e6, 0x00f8, 0x00e5, 0x007c, 0x007f +}; + +#define cet_ucs4_to_ns_4551_2_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_ns_4551_2_links[cet_ucs4_to_ns_4551_2_ct] = +{ + {0x007c, 0x7e} /* line */, + {0x00a7, 0x23} /* sign */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c6, 0x5b} /* capital letter ae */, + {0x00d8, 0x5c} /* capital letter o with stroke */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e6, 0x7b} /* small letter ae */, + {0x00f8, 0x7c} /* small letter o with stroke */ +}; + +/* +#define cet_ucs4_to_ns_4551_2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_ns_4551_2_extra[cet_ucs4_to_ns_4551_2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_ns_4551_2 = /* defined in cet.h */ +{ + cet_cs_name_ns_4551_2, /* name of character set */ + cet_cs_alias_ns_4551_2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_ns_4551_2, /* char to UCS-4 value table */ + cet_ucs4_ofs_ns_4551_2, /* first non standard character */ + cet_ucs4_cnt_ns_4551_2, /* number of values in table */ + + cet_ucs4_to_ns_4551_2_links, /* UCS-4 to char links */ + cet_ucs4_to_ns_4551_2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int ns_4551_2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x00a7, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e6, 0x00f8, 0x00e5, 0x007c, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/pt.h b/cet/pt.h new file mode 100644 index 000000000..d664042c7 --- /dev/null +++ b/cet/pt.h @@ -0,0 +1,128 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "PT" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef pt_h +#define pt_h + +#define cet_cs_name_pt "PT" + +const char *cet_cs_alias_pt[] = +{ + "PT", "ISO646-PT", "iso-ir-16", NULL +}; + +#define cet_ucs4_ofs_pt 64 +#define cet_ucs4_cnt_pt 64 + +const int cet_ucs4_map_pt[cet_ucs4_cnt_pt] = +{ + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x00b0, 0x007f +}; + +#define cet_ucs4_to_pt_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_pt_links[cet_ucs4_to_pt_ct] = +{ + {0x00a7, 0x40} /* sign */, + {0x00b0, 0x7e} /* sign */, + {0x00c3, 0x5b} /* capital letter a with tilde */, + {0x00c7, 0x5c} /* capital letter c with cedilla */, + {0x00d5, 0x5d} /* capital letter o with tilde */, + {0x00e3, 0x7b} /* small letter a with tilde */, + {0x00e7, 0x7c} /* small letter c with cedilla */, + {0x00f5, 0x7d} /* small letter o with tilde */ +}; + +/* +#define cet_ucs4_to_pt_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_pt_extra[cet_ucs4_to_pt_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_pt = /* defined in cet.h */ +{ + cet_cs_name_pt, /* name of character set */ + cet_cs_alias_pt, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_pt, /* char to UCS-4 value table */ + cet_ucs4_ofs_pt, /* first non standard character */ + cet_ucs4_cnt_pt, /* number of values in table */ + + cet_ucs4_to_pt_links, /* UCS-4 to char links */ + cet_ucs4_to_pt_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int pt_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00a7, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x00b0, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/pt2.h b/cet/pt2.h new file mode 100644 index 000000000..fcbb01c82 --- /dev/null +++ b/cet/pt2.h @@ -0,0 +1,127 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "PT2" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef pt2_h +#define pt2_h + +#define cet_cs_name_pt2 "PT2" + +const char *cet_cs_alias_pt2[] = +{ + "PT2", "ISO646-PT2", "iso-ir-84", NULL +}; + +#define cet_ucs4_ofs_pt2 64 +#define cet_ucs4_cnt_pt2 64 + +const int cet_ucs4_map_pt2[cet_ucs4_cnt_pt2] = +{ + 0x00b4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x007e, 0x007f +}; + +#define cet_ucs4_to_pt2_ct 7 + +const cet_ucs4_link_t cet_ucs4_to_pt2_links[cet_ucs4_to_pt2_ct] = +{ + {0x00b4, 0x40} /* accent */, + {0x00c3, 0x5b} /* capital letter a with tilde */, + {0x00c7, 0x5c} /* capital letter c with cedilla */, + {0x00d5, 0x5d} /* capital letter o with tilde */, + {0x00e3, 0x7b} /* small letter a with tilde */, + {0x00e7, 0x7c} /* small letter c with cedilla */, + {0x00f5, 0x7d} /* small letter o with tilde */ +}; + +/* +#define cet_ucs4_to_pt2_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_pt2_extra[cet_ucs4_to_pt2_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_pt2 = /* defined in cet.h */ +{ + cet_cs_name_pt2, /* name of character set */ + cet_cs_alias_pt2, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_pt2, /* char to UCS-4 value table */ + cet_ucs4_ofs_pt2, /* first non standard character */ + cet_ucs4_cnt_pt2, /* number of values in table */ + + cet_ucs4_to_pt2_links, /* UCS-4 to char links */ + cet_ucs4_to_pt2_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int pt2_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00b4, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c3, 0x00c7, 0x00d5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e3, 0x00e7, 0x00f5, 0x007e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/sami.h b/cet/sami.h new file mode 100644 index 000000000..4dfce1713 --- /dev/null +++ b/cet/sami.h @@ -0,0 +1,157 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "sami" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef sami_h +#define sami_h + +#define cet_cs_name_sami "sami" + +const char *cet_cs_alias_sami[] = +{ + "sami", "iso-ir-158", "lap", "latin-lap", + NULL +}; + +#define cet_ucs4_ofs_sami 160 +#define cet_ucs4_cnt_sami 80 + +const int cet_ucs4_map_sami[cet_ucs4_cnt_sami] = +{ + 0x00b4, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x02bb, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0102, 0x00c0, 0x01de, 0x01e0, 0x01e2, 0x0114, 0x00c8, 0x01e4, + 0x01e6, 0x01e8, 0x014e, 0x00d2, 0x01ea, 0x01ec, 0x01b7, 0x01ee, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0103, 0x00e0, 0x01df, 0x01e1, 0x01e3, 0x0115, 0x00e8, 0x01e5, + 0x01e7, 0x01e9, 0x014f, 0x00f2, 0x01eb, 0x01ed, 0x0292, 0x01ef +}; + +#define cet_ucs4_to_sami_ct 34 + +const cet_ucs4_link_t cet_ucs4_to_sami_links[cet_ucs4_to_sami_ct] = +{ + {0x00b4, 0xa0} /* accent */, + {0x00c0, 0xc1} /* capital letter a with grave */, + {0x00c8, 0xc6} /* capital letter e with grave */, + {0x00d2, 0xcb} /* capital letter o with grave */, + {0x00e0, 0xe1} /* small letter a with grave */, + {0x00e8, 0xe6} /* small letter e with grave */, + {0x00f2, 0xeb} /* small letter o with grave */, + {0x0102, 0xc0} /* capital letter a with breve */, + {0x0103, 0xe0} /* small letter a with breve */, + {0x0114, 0xc5} /* capital letter e with breve */, + {0x0115, 0xe5} /* small letter e with breve */, + {0x014e, 0xca} /* capital letter o with breve */, + {0x014f, 0xea} /* small letter o with breve */, + {0x01b7, 0xce} /* capital letter ezh */, + {0x01de, 0xc2} /* capital letter a with diaeresis and macron */, + {0x01df, 0xe2} /* small letter a with diaeresis and macron */, + {0x01e0, 0xc3} /* capital letter a with dot above and macron */, + {0x01e1, 0xe3} /* small letter a with dot above and macron */, + {0x01e2, 0xc4} /* capital letter ae with macron */, + {0x01e3, 0xe4} /* small letter ae with macron */, + {0x01e4, 0xc7} /* capital letter g with stroke */, + {0x01e5, 0xe7} /* small letter g with stroke */, + {0x01e6, 0xc8} /* capital letter g with caron */, + {0x01e7, 0xe8} /* small letter g with caron */, + {0x01e8, 0xc9} /* capital letter k with caron */, + {0x01e9, 0xe9} /* small letter k with caron */, + {0x01ea, 0xcc} /* capital letter o with ogonek */, + {0x01eb, 0xec} /* small letter o with ogonek */, + {0x01ec, 0xcd} /* capital letter o with ogonek and macron */, + {0x01ed, 0xed} /* small letter o with ogonek and macron */, + {0x01ee, 0xcf} /* capital letter ezh with caron */, + {0x01ef, 0xef} /* small letter ezh with caron */, + {0x0292, 0xee} /* small letter ezh (iso-ir-158 142) */, + {0x02bb, 0xb0} /* letter left half ring */ +}; + +/* +#define cet_ucs4_to_sami_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_sami_extra[cet_ucs4_to_sami_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_sami = /* defined in cet.h */ +{ + cet_cs_name_sami, /* name of character set */ + cet_cs_alias_sami, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_sami, /* char to UCS-4 value table */ + cet_ucs4_ofs_sami, /* first non standard character */ + cet_ucs4_cnt_sami, /* number of values in table */ + + cet_ucs4_to_sami_links, /* UCS-4 to char links */ + cet_ucs4_to_sami_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int sami_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00b4, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x02bb, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0102, 0x00c0, 0x01de, 0x01e0, 0x01e2, 0x0114, 0x00c8, 0x01e4, + 0x01e6, 0x01e8, 0x014e, 0x00d2, 0x01ea, 0x01ec, 0x01b7, 0x01ee, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0x0103, 0x00e0, 0x01df, 0x01e1, 0x01e3, 0x0115, 0x00e8, 0x01e5, + 0x01e7, 0x01e9, 0x014f, 0x00f2, 0x01eb, 0x01ed, 0x0292, 0x01ef, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/sen_850200_b.h b/cet/sen_850200_b.h new file mode 100644 index 000000000..0c3123199 --- /dev/null +++ b/cet/sen_850200_b.h @@ -0,0 +1,133 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "SEN_850200_B" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef sen_850200_b_h +#define sen_850200_b_h + +#define cet_cs_name_sen_850200_b "SEN_850200_B" + +const char *cet_cs_alias_sen_850200_b[] = +{ + "SEN_850200_B", "FI", "ISO646-FI", "ISO646-SE", + "iso-ir-10", "se", "SS636127", NULL +}; + +#define cet_ucs4_ofs_sen_850200_b 36 +#define cet_ucs4_cnt_sen_850200_b 92 + +const int cet_ucs4_map_sen_850200_b[cet_ucs4_cnt_sen_850200_b] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c4, + 0x00d6, 0x00c5, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e4, + 0x00f6, 0x00e5, 0x203e, 0x007f +}; + +#define cet_ucs4_to_sen_850200_b_ct 8 + +const cet_ucs4_link_t cet_ucs4_to_sen_850200_b_links[cet_ucs4_to_sen_850200_b_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x203e, 0x7e} /* overline */ +}; + +/* +#define cet_ucs4_to_sen_850200_b_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_sen_850200_b_extra[cet_ucs4_to_sen_850200_b_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_sen_850200_b = /* defined in cet.h */ +{ + cet_cs_name_sen_850200_b, /* name of character set */ + cet_cs_alias_sen_850200_b, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_sen_850200_b, /* char to UCS-4 value table */ + cet_ucs4_ofs_sen_850200_b, /* first non standard character */ + cet_ucs4_cnt_sen_850200_b, /* number of values in table */ + + cet_ucs4_to_sen_850200_b_links, /* UCS-4 to char links */ + cet_ucs4_to_sen_850200_b_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int sen_850200_b_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x203e, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/sen_850200_c.h b/cet/sen_850200_c.h new file mode 100644 index 000000000..606157b0b --- /dev/null +++ b/cet/sen_850200_c.h @@ -0,0 +1,136 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "SEN_850200_C" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef sen_850200_c_h +#define sen_850200_c_h + +#define cet_cs_name_sen_850200_c "SEN_850200_C" + +const char *cet_cs_alias_sen_850200_c[] = +{ + "SEN_850200_C", "ISO646-SE2", "iso-ir-11", "se2", + NULL +}; + +#define cet_ucs4_ofs_sen_850200_c 36 +#define cet_ucs4_cnt_sen_850200_c 92 + +const int cet_ucs4_map_sen_850200_c[cet_ucs4_cnt_sen_850200_c] = +{ + 0x00a4, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, + 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, + 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x00c9, 0x0041, 0x0042, 0x0043, + 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x00c4, + 0x00d6, 0x00c5, 0x00dc, 0x005f, 0x00e9, 0x0061, 0x0062, 0x0063, + 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x00e4, + 0x00f6, 0x00e5, 0x00fc, 0x007f +}; + +#define cet_ucs4_to_sen_850200_c_ct 11 + +const cet_ucs4_link_t cet_ucs4_to_sen_850200_c_links[cet_ucs4_to_sen_850200_c_ct] = +{ + {0x00a4, 0x24} /* sign */, + {0x00c4, 0x5b} /* capital letter a with diaeresis */, + {0x00c5, 0x5d} /* capital letter a with ring above */, + {0x00c9, 0x40} /* capital letter e with acute */, + {0x00d6, 0x5c} /* capital letter o with diaeresis */, + {0x00dc, 0x5e} /* capital letter u with diaeresis */, + {0x00e4, 0x7b} /* small letter a with diaeresis */, + {0x00e5, 0x7d} /* small letter a with ring above */, + {0x00e9, 0x60} /* small letter e with acute */, + {0x00f6, 0x7c} /* small letter o with diaeresis */, + {0x00fc, 0x7e} /* small letter u with diaeresis */ +}; + +/* +#define cet_ucs4_to_sen_850200_c_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_sen_850200_c_extra[cet_ucs4_to_sen_850200_c_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_sen_850200_c = /* defined in cet.h */ +{ + cet_cs_name_sen_850200_c, /* name of character set */ + cet_cs_alias_sen_850200_c, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_sen_850200_c, /* char to UCS-4 value table */ + cet_ucs4_ofs_sen_850200_c, /* first non standard character */ + cet_ucs4_cnt_sen_850200_c, /* number of values in table */ + + cet_ucs4_to_sen_850200_c_links, /* UCS-4 to char links */ + cet_ucs4_to_sen_850200_c_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int sen_850200_c_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x00c9, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x005f, + 0x00e9, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x00e4, 0x00f6, 0x00e5, 0x00fc, 0x007f, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +}; +*/ + +#endif diff --git a/cet/tcvn.h b/cet/tcvn.h new file mode 100644 index 000000000..894c0b025 --- /dev/null +++ b/cet/tcvn.h @@ -0,0 +1,278 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "TCVN" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef tcvn_h +#define tcvn_h + +#define cet_cs_name_tcvn "TCVN" + +const char *cet_cs_alias_tcvn[] = +{ + "TCVN", "TCVN5712-1", "TCVN5712-1:1993", "TCVN-5712", + NULL +}; + +#define cet_ucs4_ofs_tcvn 1 +#define cet_ucs4_cnt_tcvn 255 + +const int cet_ucs4_map_tcvn[cet_ucs4_cnt_tcvn] = +{ + 0x00da, 0x1ee4, 0x0003, 0x1eea, 0x1eec, 0x1eee, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x1ee8, 0x1ef0, 0x1ef2, 0x1ef6, 0x1ef8, 0x00dd, 0x1ef4, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, + 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c0, + 0x1ea2, 0x00c3, 0x00c1, 0x1ea0, 0x1eb6, 0x1eac, 0x00c8, 0x1eba, + 0x1ebc, 0x00c9, 0x1eb8, 0x1ec6, 0x00cc, 0x1ec8, 0x0128, 0x00cd, + 0x1eca, 0x00d2, 0x1ece, 0x00d5, 0x00d3, 0x1ecc, 0x1ed8, 0x1edc, + 0x1ede, 0x1ee0, 0x1eda, 0x1ee2, 0x00d9, 0x1ee6, 0x0168, -1, + 0x0102, 0x00c2, 0x00ca, 0x00d4, 0x01a0, 0x01af, 0x0110, 0x0103, + 0x00e2, 0x00ea, 0x00f4, 0x01a1, 0x01b0, 0x0111, 0x1eb0, -1, + -1, -1, -1, -1, 0x00e0, 0x1ea3, 0x00e3, 0x00e1, + 0x1ea1, 0x1eb2, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eaf, 0x1eb4, 0x1eae, + 0x1ea6, 0x1ea8, 0x1eaa, 0x1ea4, 0x1ec0, 0x1eb7, 0x1ea7, 0x1ea9, + 0x1eab, 0x1ea5, 0x1ead, 0x00e8, 0x1ec2, 0x1ebb, 0x1ebd, 0x00e9, + 0x1eb9, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ebf, 0x1ec7, 0x00ec, 0x1ec9, + 0x1ec4, 0x1ebe, 0x1ed2, 0x0129, 0x00ed, 0x1ecb, 0x00f2, 0x1ed4, + 0x1ecf, 0x00f5, 0x00f3, 0x1ecd, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed1, + 0x1ed9, 0x1edd, 0x1edf, 0x1ee1, 0x1edb, 0x1ee3, 0x00f9, 0x1ed6, + 0x1ee7, 0x0169, 0x00fa, 0x1ee5, 0x1eeb, 0x1eed, 0x1eef, 0x1ee9, + 0x1ef1, 0x1ef3, 0x1ef7, 0x1ef9, 0x00fd, 0x1ef5, 0x1ed0 +}; + +#define cet_ucs4_to_tcvn_ct 133 + +const cet_ucs4_link_t cet_ucs4_to_tcvn_links[cet_ucs4_to_tcvn_ct] = +{ + {0x00c0, 0x80} /* capital letter a with grave */, + {0x00c1, 0x83} /* capital letter a with acute */, + {0x00c2, 0xa2} /* capital letter a with circumflex */, + {0x00c3, 0x82} /* capital letter a with tilde */, + {0x00c8, 0x87} /* capital letter e with grave */, + {0x00c9, 0x8a} /* capital letter e with acute */, + {0x00ca, 0xa3} /* capital letter e with circumflex */, + {0x00cc, 0x8d} /* capital letter i with grave */, + {0x00cd, 0x90} /* capital letter i with acute */, + {0x00d2, 0x92} /* capital letter o with grave */, + {0x00d3, 0x95} /* capital letter o with acute */, + {0x00d4, 0xa4} /* capital letter o with circumflex */, + {0x00d5, 0x94} /* capital letter o with tilde */, + {0x00d9, 0x9d} /* capital letter u with grave */, + {0x00da, 0x01} /* capital letter u with acute */, + {0x00dd, 0x16} /* capital letter y with acute */, + {0x00e0, 0xb5} /* small letter a with grave */, + {0x00e1, 0xb8} /* small letter a with acute */, + {0x00e2, 0xa9} /* small letter a with circumflex */, + {0x00e3, 0xb7} /* small letter a with tilde */, + {0x00e8, 0xcc} /* small letter e with grave */, + {0x00e9, 0xd0} /* small letter e with acute */, + {0x00ea, 0xaa} /* small letter e with circumflex */, + {0x00ec, 0xd7} /* small letter i with grave */, + {0x00ed, 0xdd} /* small letter i with acute */, + {0x00f2, 0xdf} /* small letter o with grave */, + {0x00f3, 0xe3} /* small letter o with acute */, + {0x00f4, 0xab} /* small letter o with circumflex */, + {0x00f5, 0xe2} /* small letter o with tilde */, + {0x00f9, 0xef} /* small letter u with grave */, + {0x00fa, 0xf3} /* small letter u with acute */, + {0x0102, 0xa1} /* capital letter a with breve */, + {0x0103, 0xa8} /* small letter a with breve */, + {0x0110, 0xa7} /* capital letter d with stroke */, + {0x0111, 0xae} /* small letter d with stroke */, + {0x0128, 0x8f} /* capital letter i with tilde */, + {0x0129, 0xdc} /* small letter i with tilde */, + {0x0168, 0x9f} /* capital letter u with tilde */, + {0x0169, 0xf2} /* small letter u with tilde */, + {0x01a0, 0xa5} /* capital letter o with horn */, + {0x01a1, 0xac} /* small letter o with horn */, + {0x01af, 0xa6} /* capital letter u with horn */, + {0x01b0, 0xad} /* small letter u with horn */, + {0x1ea0, 0x84} /* capital letter a with dot below */, + {0x1ea1, 0xb9} /* small letter a with dot below */, + {0x1ea2, 0x81} /* capital letter a with hook above */, + {0x1ea3, 0xb6} /* small letter a with hook above */, + {0x1ea4, 0xc4} /* capital letter a with circumflex and acute */, + {0x1ea5, 0xca} /* small letter a with circumflex and acute */, + {0x1ea6, 0xc1} /* capital letter a with circumflex and grave */, + {0x1ea7, 0xc7} /* small letter a with circumflex and grave */, + {0x1ea8, 0xc2} /* capital letter a with circumflex and hook above */, + {0x1ea9, 0xc8} /* small letter a with circumflex and hook above */, + {0x1eaa, 0xc3} /* capital letter a with circumflex and tilde */, + {0x1eab, 0xc9} /* small letter a with circumflex and tilde */, + {0x1eac, 0x86} /* latine a accent circonflexe et point souscrit */, + {0x1ead, 0xcb} /* latine a accent circonflexe et point souscrit */, + {0x1eae, 0xc0} /* capital letter a with breve and acute */, + {0x1eaf, 0xbe} /* small letter a with breve and acute */, + {0x1eb0, 0xaf} /* capital letter a with breve and grave */, + {0x1eb1, 0xbb} /* small letter a with breve and grave */, + {0x1eb2, 0xba} /* capital letter a with breve and hook above */, + {0x1eb3, 0xbc} /* small letter a with breve and hook above */, + {0x1eb4, 0xbf} /* capital letter a with breve and tilde */, + {0x1eb5, 0xbd} /* small letter a with breve and tilde */, + {0x1eb6, 0x85} /* latine a brève et point souscrit */, + {0x1eb7, 0xc6} /* latine a brève et point souscrit */, + {0x1eb8, 0x8b} /* capital letter e with dot below */, + {0x1eb9, 0xd1} /* small letter e with dot below */, + {0x1eba, 0x88} /* capital letter e with hook above */, + {0x1ebb, 0xce} /* small letter e with hook above */, + {0x1ebc, 0x89} /* capital letter e with tilde */, + {0x1ebd, 0xcf} /* small letter e with tilde */, + {0x1ebe, 0xda} /* capital letter e with circumflex and acute */, + {0x1ebf, 0xd5} /* small letter e with circumflex and acute */, + {0x1ec0, 0xc5} /* capital letter e with circumflex and grave */, + {0x1ec1, 0xd2} /* small letter e with circumflex and grave */, + {0x1ec2, 0xcd} /* capital letter e with circumflex and hook above */, + {0x1ec3, 0xd3} /* small letter e with circumflex and hook above */, + {0x1ec4, 0xd9} /* capital letter e with circumflex and tilde */, + {0x1ec5, 0xd4} /* small letter e with circumflex and tilde */, + {0x1ec6, 0x8c} /* latine e accent circonflexe et point souscrit */, + {0x1ec7, 0xd6} /* latine e accent circonflexe et point souscrit */, + {0x1ec8, 0x8e} /* capital letter i with hook above */, + {0x1ec9, 0xd8} /* small letter i with hook above */, + {0x1eca, 0x91} /* capital letter i with dot below */, + {0x1ecb, 0xde} /* small letter i with dot below */, + {0x1ecc, 0x96} /* capital letter o with dot below */, + {0x1ecd, 0xe4} /* small letter o with dot below */, + {0x1ece, 0x93} /* capital letter o with hook above */, + {0x1ecf, 0xe1} /* small letter o with hook above */, + {0x1ed0, 0xff} /* capital letter o with circumflex and acute */, + {0x1ed1, 0xe8} /* small letter o with circumflex and acute */, + {0x1ed2, 0xdb} /* capital letter o with circumflex and grave */, + {0x1ed3, 0xe5} /* small letter o with circumflex and grave */, + {0x1ed4, 0xe0} /* capital letter o with circumflex and hook above */, + {0x1ed5, 0xe6} /* small letter o with circumflex and hook above */, + {0x1ed6, 0xf0} /* capital letter o with circumflex and tilde */, + {0x1ed7, 0xe7} /* small letter o with circumflex and tilde */, + {0x1ed8, 0x97} /* latine o accent circonflexe et point souscrit */, + {0x1ed9, 0xe9} /* latine o accent circonflexe et point souscrit */, + {0x1eda, 0x9b} /* capital letter o with horn and acute */, + {0x1edb, 0xed} /* small letter o with horn and acute */, + {0x1edc, 0x98} /* capital letter o with horn and grave */, + {0x1edd, 0xea} /* small letter o with horn and grave */, + {0x1ede, 0x99} /* capital letter o with horn and hook above */, + {0x1edf, 0xeb} /* small letter o with horn and hook above */, + {0x1ee0, 0x9a} /* capital letter o with horn and tilde */, + {0x1ee1, 0xec} /* small letter o with horn and tilde */, + {0x1ee2, 0x9c} /* latine o cornu point souscrit */, + {0x1ee3, 0xee} /* latine o cornu point souscrit */, + {0x1ee4, 0x02} /* capital letter u with dot below */, + {0x1ee5, 0xf4} /* small letter u with dot below */, + {0x1ee6, 0x9e} /* capital letter u with hook above */, + {0x1ee7, 0xf1} /* small letter u with hook above */, + {0x1ee8, 0x11} /* capital letter u with horn and acute */, + {0x1ee9, 0xf8} /* small letter u with horn and acute */, + {0x1eea, 0x04} /* capital letter u with horn and grave */, + {0x1eeb, 0xf5} /* small letter u with horn and grave */, + {0x1eec, 0x05} /* capital letter u with horn and hook above */, + {0x1eed, 0xf6} /* small letter u with horn and hook above */, + {0x1eee, 0x06} /* capital letter u with horn and tilde */, + {0x1eef, 0xf7} /* small letter u with horn and tilde */, + {0x1ef0, 0x12} /* latine u cornu point souscrit */, + {0x1ef1, 0xf9} /* latine u cornu point souscrit */, + {0x1ef2, 0x13} /* capital letter y with grave */, + {0x1ef3, 0xfa} /* small letter y with grave */, + {0x1ef4, 0x17} /* capital letter y with dot below */, + {0x1ef5, 0xfe} /* small letter y with dot below */, + {0x1ef6, 0x14} /* capital letter y with hook above */, + {0x1ef7, 0xfb} /* small letter y with hook above */, + {0x1ef8, 0x15} /* capital letter y with tilde */, + {0x1ef9, 0xfc} /* small letter y with tilde */ +}; + +/* +#define cet_ucs4_to_tcvn_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_tcvn_extra[cet_ucs4_to_tcvn_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_tcvn = /* defined in cet.h */ +{ + cet_cs_name_tcvn, /* name of character set */ + cet_cs_alias_tcvn, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_tcvn, /* char to UCS-4 value table */ + cet_ucs4_ofs_tcvn, /* first non standard character */ + cet_ucs4_cnt_tcvn, /* number of values in table */ + + cet_ucs4_to_tcvn_links, /* UCS-4 to char links */ + cet_ucs4_to_tcvn_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int tcvn_ucs4_full_map[] = +{ + 0x0000, 0x00da, 0x1ee4, 0x0003, 0x1eea, 0x1eec, 0x1eee, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x1ee8, 0x1ef0, 0x1ef2, 0x1ef6, 0x1ef8, 0x00dd, 0x1ef4, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c0, 0x1ea2, 0x00c3, 0x00c1, 0x1ea0, 0x1eb6, 0x1eac, 0x00c8, + 0x1eba, 0x1ebc, 0x00c9, 0x1eb8, 0x1ec6, 0x00cc, 0x1ec8, 0x0128, + 0x00cd, 0x1eca, 0x00d2, 0x1ece, 0x00d5, 0x00d3, 0x1ecc, 0x1ed8, + 0x1edc, 0x1ede, 0x1ee0, 0x1eda, 0x1ee2, 0x00d9, 0x1ee6, 0x0168, + -1, 0x0102, 0x00c2, 0x00ca, 0x00d4, 0x01a0, 0x01af, 0x0110, + 0x0103, 0x00e2, 0x00ea, 0x00f4, 0x01a1, 0x01b0, 0x0111, 0x1eb0, + -1, -1, -1, -1, -1, 0x00e0, 0x1ea3, 0x00e3, + 0x00e1, 0x1ea1, 0x1eb2, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eaf, 0x1eb4, + 0x1eae, 0x1ea6, 0x1ea8, 0x1eaa, 0x1ea4, 0x1ec0, 0x1eb7, 0x1ea7, + 0x1ea9, 0x1eab, 0x1ea5, 0x1ead, 0x00e8, 0x1ec2, 0x1ebb, 0x1ebd, + 0x00e9, 0x1eb9, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ebf, 0x1ec7, 0x00ec, + 0x1ec9, 0x1ec4, 0x1ebe, 0x1ed2, 0x0129, 0x00ed, 0x1ecb, 0x00f2, + 0x1ed4, 0x1ecf, 0x00f5, 0x00f3, 0x1ecd, 0x1ed3, 0x1ed5, 0x1ed7, + 0x1ed1, 0x1ed9, 0x1edd, 0x1edf, 0x1ee1, 0x1edb, 0x1ee3, 0x00f9, + 0x1ed6, 0x1ee7, 0x0169, 0x00fa, 0x1ee5, 0x1eeb, 0x1eed, 0x1eef, + 0x1ee9, 0x1ef1, 0x1ef3, 0x1ef7, 0x1ef9, 0x00fd, 0x1ef5, 0x1ed0 +}; +*/ + +#endif diff --git a/cet/viscii.h b/cet/viscii.h new file mode 100644 index 000000000..43dfbe3eb --- /dev/null +++ b/cet/viscii.h @@ -0,0 +1,247 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "VISCII" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef viscii_h +#define viscii_h + +#define cet_cs_name_viscii "VISCII" + +const char *cet_cs_alias_viscii[] = +{ + "VISCII", "csVISCII", "VISCII1.1-1", NULL +}; + +#define cet_ucs4_ofs_viscii 2 +#define cet_ucs4_cnt_viscii 254 + +const int cet_ucs4_map_viscii[cet_ucs4_cnt_viscii] = +{ + 0x1eb2, 0x0003, 0x0004, 0x1eb4, 0x1eaa, 0x0007, 0x0008, 0x0009, + 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x1ef6, 0x0015, 0x0016, 0x0017, 0x0018, 0x1ef8, + 0x001a, 0x001b, 0x001c, 0x001d, 0x1ef4, 0x001f, 0x0020, 0x0021, + 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, + 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, + 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, + 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, + 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x1ea0, 0x1eae, + 0x1eb0, 0x1eb6, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eac, 0x1ebc, 0x1eb8, + 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ed0, 0x1ed2, 0x1ed4, + 0x1ed6, 0x1ed8, 0x1ee2, 0x1eda, 0x1edc, 0x1ede, 0x1eca, 0x1ece, + 0x1ecc, 0x1ec8, 0x1ee6, 0x0168, 0x1ee4, 0x1ef2, 0x00d5, 0x1eaf, + 0x1eb1, 0x1eb7, 0x1ea5, 0x1ea7, 0x1ea9, 0x1ead, 0x1ebd, 0x1eb9, + 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ed1, 0x1ed3, 0x1ed5, + 0x1ed7, 0x1ee0, 0x01a0, 0x1ed9, 0x1edd, 0x1edf, 0x1ecb, 0x1ef0, + 0x1ee8, 0x1eea, 0x1eec, 0x01a1, 0x1edb, 0x01af, 0x00c0, 0x00c1, + 0x00c2, 0x00c3, 0x1ea2, 0x0102, 0x1eb3, 0x1eb5, 0x00c8, 0x00c9, + 0x00ca, 0x1eba, 0x00cc, 0x00cd, 0x0128, 0x1ef3, 0x0110, 0x1ee9, + 0x00d2, 0x00d3, 0x00d4, 0x1ea1, 0x1ef7, 0x1eeb, 0x1eed, 0x00d9, + 0x00da, 0x1ef9, 0x1ef5, 0x00dd, 0x1ee1, 0x01b0, 0x00e0, 0x00e1, + 0x00e2, 0x00e3, 0x1ea3, 0x0103, 0x1eef, 0x1eab, 0x00e8, 0x00e9, + 0x00ea, 0x1ebb, 0x00ec, 0x00ed, 0x0129, 0x1ec9, 0x0111, 0x1ef1, + 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x1ecf, 0x1ecd, 0x1ee5, 0x00f9, + 0x00fa, 0x0169, 0x1ee7, 0x00fd, 0x1ee3, 0x1eee +}; + +#define cet_ucs4_to_viscii_ct 103 + +const cet_ucs4_link_t cet_ucs4_to_viscii_links[cet_ucs4_to_viscii_ct] = +{ + {0x00d5, 0xa0} /* capital letter o with tilde */, + {0x0102, 0xc5} /* capital letter a with breve */, + {0x0103, 0xe5} /* small letter a with breve */, + {0x0110, 0xd0} /* capital letter d with stroke */, + {0x0111, 0xf0} /* small letter d with stroke */, + {0x0128, 0xce} /* capital letter i with tilde */, + {0x0129, 0xee} /* small letter i with tilde */, + {0x0168, 0x9d} /* capital letter u with tilde */, + {0x0169, 0xfb} /* small letter u with tilde */, + {0x01a0, 0xb4} /* capital letter o with horn */, + {0x01a1, 0xbd} /* small letter o with horn */, + {0x01af, 0xbf} /* capital letter u with horn */, + {0x01b0, 0xdf} /* small letter u with horn */, + {0x1ea0, 0x80} /* capital letter a with dot below */, + {0x1ea1, 0xd5} /* small letter a with dot below */, + {0x1ea2, 0xc4} /* capital letter a with hook above */, + {0x1ea3, 0xe4} /* small letter a with hook above */, + {0x1ea4, 0x84} /* capital letter a with circumflex and acute */, + {0x1ea5, 0xa4} /* small letter a with circumflex and acute */, + {0x1ea6, 0x85} /* capital letter a with circumflex and grave */, + {0x1ea7, 0xa5} /* small letter a with circumflex and grave */, + {0x1ea8, 0x86} /* capital letter a with circumflex and hook above */, + {0x1ea9, 0xa6} /* small letter a with circumflex and hook above */, + {0x1eaa, 0x06} /* capital letter a with circumflex and tilde */, + {0x1eab, 0xe7} /* small letter a with circumflex and tilde */, + {0x1eac, 0x87} /* latine a accent circonflexe et point souscrit */, + {0x1ead, 0xa7} /* latine a accent circonflexe et point souscrit */, + {0x1eae, 0x81} /* capital letter a with breve and acute */, + {0x1eaf, 0xa1} /* small letter a with breve and acute */, + {0x1eb0, 0x82} /* capital letter a with breve and grave */, + {0x1eb1, 0xa2} /* small letter a with breve and grave */, + {0x1eb2, 0x02} /* capital letter a with breve and hook above */, + {0x1eb3, 0xc6} /* small letter a with breve and hook above */, + {0x1eb4, 0x05} /* capital letter a with breve and tilde */, + {0x1eb5, 0xc7} /* small letter a with breve and tilde */, + {0x1eb6, 0x83} /* latine a brève et point souscrit */, + {0x1eb7, 0xa3} /* latine a brève et point souscrit */, + {0x1eb8, 0x89} /* capital letter e with dot below */, + {0x1eb9, 0xa9} /* small letter e with dot below */, + {0x1eba, 0xcb} /* capital letter e with hook above */, + {0x1ebb, 0xeb} /* small letter e with hook above */, + {0x1ebc, 0x88} /* capital letter e with tilde */, + {0x1ebd, 0xa8} /* small letter e with tilde */, + {0x1ebe, 0x8a} /* capital letter e with circumflex and acute */, + {0x1ebf, 0xaa} /* small letter e with circumflex and acute */, + {0x1ec0, 0x8b} /* capital letter e with circumflex and grave */, + {0x1ec1, 0xab} /* small letter e with circumflex and grave */, + {0x1ec2, 0x8c} /* capital letter e with circumflex and hook above */, + {0x1ec3, 0xac} /* small letter e with circumflex and hook above */, + {0x1ec4, 0x8d} /* capital letter e with circumflex and tilde */, + {0x1ec5, 0xad} /* small letter e with circumflex and tilde */, + {0x1ec6, 0x8e} /* latine e accent circonflexe et point souscrit */, + {0x1ec7, 0xae} /* latine e accent circonflexe et point souscrit */, + {0x1ec8, 0x9b} /* capital letter i with hook above */, + {0x1ec9, 0xef} /* small letter i with hook above */, + {0x1eca, 0x98} /* capital letter i with dot below */, + {0x1ecb, 0xb8} /* small letter i with dot below */, + {0x1ecc, 0x9a} /* capital letter o with dot below */, + {0x1ecd, 0xf7} /* small letter o with dot below */, + {0x1ece, 0x99} /* capital letter o with hook above */, + {0x1ecf, 0xf6} /* small letter o with hook above */, + {0x1ed0, 0x8f} /* capital letter o with circumflex and acute */, + {0x1ed1, 0xaf} /* small letter o with circumflex and acute */, + {0x1ed2, 0x90} /* capital letter o with circumflex and grave */, + {0x1ed3, 0xb0} /* small letter o with circumflex and grave */, + {0x1ed4, 0x91} /* capital letter o with circumflex and hook above */, + {0x1ed5, 0xb1} /* small letter o with circumflex and hook above */, + {0x1ed6, 0x92} /* capital letter o with circumflex and tilde */, + {0x1ed7, 0xb2} /* small letter o with circumflex and tilde */, + {0x1ed8, 0x93} /* latine o accent circonflexe et point souscrit */, + {0x1ed9, 0xb5} /* latine o accent circonflexe et point souscrit */, + {0x1eda, 0x95} /* capital letter o with horn and acute */, + {0x1edb, 0xbe} /* small letter o with horn and acute */, + {0x1edc, 0x96} /* capital letter o with horn and grave */, + {0x1edd, 0xb6} /* small letter o with horn and grave */, + {0x1ede, 0x97} /* capital letter o with horn and hook above */, + {0x1edf, 0xb7} /* small letter o with horn and hook above */, + {0x1ee0, 0xb3} /* capital letter o with horn and tilde */, + {0x1ee1, 0xde} /* small letter o with horn and tilde */, + {0x1ee2, 0x94} /* latine o cornu point souscrit */, + {0x1ee3, 0xfe} /* latine o cornu point souscrit */, + {0x1ee4, 0x9e} /* capital letter u with dot below */, + {0x1ee5, 0xf8} /* small letter u with dot below */, + {0x1ee6, 0x9c} /* capital letter u with hook above */, + {0x1ee7, 0xfc} /* small letter u with hook above */, + {0x1ee8, 0xba} /* capital letter u with horn and acute */, + {0x1ee9, 0xd1} /* small letter u with horn and acute */, + {0x1eea, 0xbb} /* capital letter u with horn and grave */, + {0x1eeb, 0xd7} /* small letter u with horn and grave */, + {0x1eec, 0xbc} /* capital letter u with horn and hook above */, + {0x1eed, 0xd8} /* small letter u with horn and hook above */, + {0x1eee, 0xff} /* capital letter u with horn and tilde */, + {0x1eef, 0xe6} /* small letter u with horn and tilde */, + {0x1ef0, 0xb9} /* latine u cornu point souscrit */, + {0x1ef1, 0xf1} /* latine u cornu point souscrit */, + {0x1ef2, 0x9f} /* capital letter y with grave */, + {0x1ef3, 0xcf} /* small letter y with grave */, + {0x1ef4, 0x1e} /* capital letter y with dot below */, + {0x1ef5, 0xdc} /* small letter y with dot below */, + {0x1ef6, 0x14} /* capital letter y with hook above */, + {0x1ef7, 0xd6} /* small letter y with hook above */, + {0x1ef8, 0x19} /* capital letter y with tilde */, + {0x1ef9, 0xdb} /* small letter y with tilde */ +}; + +/* +#define cet_ucs4_to_viscii_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_viscii_extra[cet_ucs4_to_viscii_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_viscii = /* defined in cet.h */ +{ + cet_cs_name_viscii, /* name of character set */ + cet_cs_alias_viscii, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_viscii, /* char to UCS-4 value table */ + cet_ucs4_ofs_viscii, /* first non standard character */ + cet_ucs4_cnt_viscii, /* number of values in table */ + + cet_ucs4_to_viscii_links, /* UCS-4 to char links */ + cet_ucs4_to_viscii_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int viscii_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x1eb2, 0x0003, 0x0004, 0x1eb4, 0x1eaa, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x1ef6, 0x0015, 0x0016, 0x0017, + 0x0018, 0x1ef8, 0x001a, 0x001b, 0x001c, 0x001d, 0x1ef4, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x1ea0, 0x1eae, 0x1eb0, 0x1eb6, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eac, + 0x1ebc, 0x1eb8, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ed0, + 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1ee2, 0x1eda, 0x1edc, 0x1ede, + 0x1eca, 0x1ece, 0x1ecc, 0x1ec8, 0x1ee6, 0x0168, 0x1ee4, 0x1ef2, + 0x00d5, 0x1eaf, 0x1eb1, 0x1eb7, 0x1ea5, 0x1ea7, 0x1ea9, 0x1ead, + 0x1ebd, 0x1eb9, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ed1, + 0x1ed3, 0x1ed5, 0x1ed7, 0x1ee0, 0x01a0, 0x1ed9, 0x1edd, 0x1edf, + 0x1ecb, 0x1ef0, 0x1ee8, 0x1eea, 0x1eec, 0x01a1, 0x1edb, 0x01af, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x1ea2, 0x0102, 0x1eb3, 0x1eb5, + 0x00c8, 0x00c9, 0x00ca, 0x1eba, 0x00cc, 0x00cd, 0x0128, 0x1ef3, + 0x0110, 0x1ee9, 0x00d2, 0x00d3, 0x00d4, 0x1ea1, 0x1ef7, 0x1eeb, + 0x1eed, 0x00d9, 0x00da, 0x1ef9, 0x1ef5, 0x00dd, 0x1ee1, 0x01b0, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x1ea3, 0x0103, 0x1eef, 0x1eab, + 0x00e8, 0x00e9, 0x00ea, 0x1ebb, 0x00ec, 0x00ed, 0x0129, 0x1ec9, + 0x0111, 0x1ef1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x1ecf, 0x1ecd, + 0x1ee5, 0x00f9, 0x00fa, 0x0169, 0x1ee7, 0x00fd, 0x1ee3, 0x1eee +}; +*/ + +#endif diff --git a/cet/vps.h b/cet/vps.h new file mode 100644 index 000000000..73bf86ee4 --- /dev/null +++ b/cet/vps.h @@ -0,0 +1,255 @@ +/* + + Data automatically generated from recode output: + + 'recode -lf "VPS" 2>/dev/null' + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#ifndef vps_h +#define vps_h + +#define cet_cs_name_vps "VPS" + +const char *cet_cs_alias_vps[] = +{ + "VPS", NULL +}; + +#define cet_ucs4_ofs_vps 2 +#define cet_ucs4_cnt_vps 254 + +const int cet_ucs4_map_vps[cet_ucs4_cnt_vps] = +{ + 0x1ea0, 0x1eac, 0x1eb6, 0x1eb8, 0x1ec6, 0x0007, 0x0008, 0x0009, + 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x1eca, 0x1ecc, + 0x1ed8, 0x1ee2, 0x1ee4, 0x1ef0, 0x0016, 0x0017, 0x0018, 0x1ef4, + 0x001a, 0x001b, 0x1eaa, 0x1eee, 0x001e, 0x001f, 0x0020, 0x0021, + 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, + 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, + 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, + 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, + 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, + 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, + 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, + 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c0, 0x1ea2, + 0x00c3, 0x1ea4, 0x1ea6, 0x1ea8, 0x1ecd, 0x1ed7, 0x0102, 0x1ebf, + 0x1ec1, 0x1ec3, 0x1ec7, 0x1eae, 0x1eb0, 0x1eb2, 0x1ebe, -1, + -1, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ed0, 0x1ed2, 0x1ed4, -1, + 0x00fd, 0x1ef7, 0x1ef5, 0x1eda, 0x1edc, 0x1ede, -1, 0x1eaf, + 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1ee0, 0x1edb, 0x00d9, 0x1edd, + 0x1edf, 0x1ee1, 0x0168, 0x1ee8, 0x1ee3, 0x1eea, 0x1ed5, 0x1eec, + 0x1ef2, 0x1ef8, 0x00cd, 0x00cc, 0x1ed9, 0x1ec8, 0x0128, 0x00d3, + 0x1eed, 0x1eef, 0x00d2, 0x1ece, 0x00d5, 0x1ef1, 0x1ea7, 0x00c1, + 0x00c2, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, 0x0111, 0x1ebb, 0x00c9, + 0x00ca, 0x1eb9, 0x1ec9, 0x1ec5, 0x1ecb, 0x1ef9, 0x01af, 0x1ee6, + 0x1ed3, 0x1ed1, 0x00d4, 0x1ecf, 0x01a1, 0x00c8, 0x1eeb, 0x1ee9, + 0x00da, 0x0169, 0x01b0, 0x00dd, 0x1eba, -1, 0x00e0, 0x00e1, + 0x00e2, 0x00e3, 0x1ea3, 0x1ea1, 0x0103, -1, 0x00e8, 0x00e9, + 0x00ea, 0x1ebd, 0x00ec, 0x00ed, -1, 0x0129, 0x1eb4, 0x0110, + 0x00f2, 0x00f3, 0x00f4, 0x00f5, -1, 0x01a0, 0x1ee5, 0x00f9, + 0x00fa, 0x1ee7, -1, 0x1ef6, 0x1ebc, 0x1ef3 +}; + +#define cet_ucs4_to_vps_ct 111 + +const cet_ucs4_link_t cet_ucs4_to_vps_links[cet_ucs4_to_vps_ct] = +{ + {0x00c0, 0x80} /* capital letter a with grave */, + {0x00c3, 0x82} /* capital letter a with tilde */, + {0x00c8, 0xd7} /* capital letter e with grave */, + {0x00cc, 0xb5} /* capital letter i with grave */, + {0x00cd, 0xb4} /* capital letter i with acute */, + {0x00d2, 0xbc} /* capital letter o with grave */, + {0x00d3, 0xb9} /* capital letter o with acute */, + {0x00d5, 0xbe} /* capital letter o with tilde */, + {0x00d9, 0xa8} /* capital letter u with grave */, + {0x00fd, 0x9a} /* small letter y with acute */, + {0x0102, 0x88} /* capital letter a with breve */, + {0x0103, 0xe6} /* small letter a with breve */, + {0x0110, 0xf1} /* capital letter d with stroke */, + {0x0111, 0xc7} /* small letter d with stroke */, + {0x0128, 0xb8} /* capital letter i with tilde */, + {0x0129, 0xef} /* small letter i with tilde */, + {0x0168, 0xac} /* capital letter u with tilde */, + {0x0169, 0xdb} /* small letter u with tilde */, + {0x01a0, 0xf7} /* capital letter o with horn */, + {0x01a1, 0xd6} /* small letter o with horn */, + {0x01af, 0xd0} /* capital letter u with horn */, + {0x01b0, 0xdc} /* small letter u with horn */, + {0x1ea0, 0x02} /* capital letter a with dot below */, + {0x1ea1, 0xe5} /* small letter a with dot below */, + {0x1ea2, 0x81} /* capital letter a with hook above */, + {0x1ea3, 0xe4} /* small letter a with hook above */, + {0x1ea4, 0x83} /* capital letter a with circumflex and acute */, + {0x1ea5, 0xc3} /* small letter a with circumflex and acute */, + {0x1ea6, 0x84} /* capital letter a with circumflex and grave */, + {0x1ea7, 0xc0} /* small letter a with circumflex and grave */, + {0x1ea8, 0x85} /* capital letter a with circumflex and hook above */, + {0x1ea9, 0xc4} /* small letter a with circumflex and hook above */, + {0x1eaa, 0x1c} /* capital letter a with circumflex and tilde */, + {0x1eab, 0xc5} /* small letter a with circumflex and tilde */, + {0x1eac, 0x03} /* latine a accent circonflexe et point souscrit */, + {0x1ead, 0xc6} /* latine a accent circonflexe et point souscrit */, + {0x1eae, 0x8d} /* capital letter a with breve and acute */, + {0x1eaf, 0xa1} /* small letter a with breve and acute */, + {0x1eb0, 0x8e} /* capital letter a with breve and grave */, + {0x1eb1, 0xa2} /* small letter a with breve and grave */, + {0x1eb2, 0x8f} /* capital letter a with breve and hook above */, + {0x1eb3, 0xa3} /* small letter a with breve and hook above */, + {0x1eb4, 0xf0} /* capital letter a with breve and tilde */, + {0x1eb5, 0xa4} /* small letter a with breve and tilde */, + {0x1eb6, 0x04} /* latine a brève et point souscrit */, + {0x1eb7, 0xa5} /* latine a brève et point souscrit */, + {0x1eb8, 0x05} /* capital letter e with dot below */, + {0x1eb9, 0xcb} /* small letter e with dot below */, + {0x1eba, 0xde} /* capital letter e with hook above */, + {0x1ebb, 0xc8} /* small letter e with hook above */, + {0x1ebc, 0xfe} /* capital letter e with tilde */, + {0x1ebd, 0xeb} /* small letter e with tilde */, + {0x1ebe, 0x90} /* capital letter e with circumflex and acute */, + {0x1ebf, 0x89} /* small letter e with circumflex and acute */, + {0x1ec0, 0x93} /* capital letter e with circumflex and grave */, + {0x1ec1, 0x8a} /* small letter e with circumflex and grave */, + {0x1ec2, 0x94} /* capital letter e with circumflex and hook above */, + {0x1ec3, 0x8b} /* small letter e with circumflex and hook above */, + {0x1ec4, 0x95} /* capital letter e with circumflex and tilde */, + {0x1ec5, 0xcd} /* small letter e with circumflex and tilde */, + {0x1ec6, 0x06} /* latine e accent circonflexe et point souscrit */, + {0x1ec7, 0x8c} /* latine e accent circonflexe et point souscrit */, + {0x1ec8, 0xb7} /* capital letter i with hook above */, + {0x1ec9, 0xcc} /* small letter i with hook above */, + {0x1eca, 0x10} /* capital letter i with dot below */, + {0x1ecb, 0xce} /* small letter i with dot below */, + {0x1ecc, 0x11} /* capital letter o with dot below */, + {0x1ecd, 0x86} /* small letter o with dot below */, + {0x1ece, 0xbd} /* capital letter o with hook above */, + {0x1ecf, 0xd5} /* small letter o with hook above */, + {0x1ed0, 0x96} /* capital letter o with circumflex and acute */, + {0x1ed1, 0xd3} /* small letter o with circumflex and acute */, + {0x1ed2, 0x97} /* capital letter o with circumflex and grave */, + {0x1ed3, 0xd2} /* small letter o with circumflex and grave */, + {0x1ed4, 0x98} /* capital letter o with circumflex and hook above */, + {0x1ed5, 0xb0} /* small letter o with circumflex and hook above */, + {0x1ed7, 0x87} /* small letter o with circumflex and tilde */, + {0x1ed8, 0x12} /* latine o accent circonflexe et point souscrit */, + {0x1ed9, 0xb6} /* latine o accent circonflexe et point souscrit */, + {0x1eda, 0x9d} /* capital letter o with horn and acute */, + {0x1edb, 0xa7} /* small letter o with horn and acute */, + {0x1edc, 0x9e} /* capital letter o with horn and grave */, + {0x1edd, 0xa9} /* small letter o with horn and grave */, + {0x1ede, 0x9f} /* capital letter o with horn and hook above */, + {0x1edf, 0xaa} /* small letter o with horn and hook above */, + {0x1ee0, 0xa6} /* capital letter o with horn and tilde */, + {0x1ee1, 0xab} /* small letter o with horn and tilde */, + {0x1ee2, 0x13} /* latine o cornu point souscrit */, + {0x1ee3, 0xae} /* latine o cornu point souscrit */, + {0x1ee4, 0x14} /* capital letter u with dot below */, + {0x1ee5, 0xf8} /* small letter u with dot below */, + {0x1ee6, 0xd1} /* capital letter u with hook above */, + {0x1ee7, 0xfb} /* small letter u with hook above */, + {0x1ee8, 0xad} /* capital letter u with horn and acute */, + {0x1ee9, 0xd9} /* small letter u with horn and acute */, + {0x1eea, 0xaf} /* capital letter u with horn and grave */, + {0x1eeb, 0xd8} /* small letter u with horn and grave */, + {0x1eec, 0xb1} /* capital letter u with horn and hook above */, + {0x1eed, 0xba} /* small letter u with horn and hook above */, + {0x1eee, 0x1d} /* capital letter u with horn and tilde */, + {0x1eef, 0xbb} /* small letter u with horn and tilde */, + {0x1ef0, 0x15} /* latine u cornu point souscrit */, + {0x1ef1, 0xbf} /* latine u cornu point souscrit */, + {0x1ef2, 0xb2} /* capital letter y with grave */, + {0x1ef3, 0xff} /* small letter y with grave */, + {0x1ef4, 0x19} /* capital letter y with dot below */, + {0x1ef5, 0x9c} /* small letter y with dot below */, + {0x1ef6, 0xfd} /* capital letter y with hook above */, + {0x1ef7, 0x9b} /* small letter y with hook above */, + {0x1ef8, 0xb3} /* capital letter y with tilde */, + {0x1ef9, 0xcf} /* small letter y with tilde */ +}; + +/* +#define cet_ucs4_to_vps_extra_ct 0 +const cet_ucs4_link_t cet_ucs4_to_vps_extra[cet_ucs4_to_vps_extra_ct] = {}; +*/ + +cet_cs_vec_t cet_cs_vec_vps = /* defined in cet.h */ +{ + cet_cs_name_vps, /* name of character set */ + cet_cs_alias_vps, /* alias table */ + + NULL, /* ... to UCS-4 converter (multi-byte) */ + NULL, /* UCS-4 to ... converter (multi-byte) */ + + cet_ucs4_map_vps, /* char to UCS-4 value table */ + cet_ucs4_ofs_vps, /* first non standard character */ + cet_ucs4_cnt_vps, /* number of values in table */ + + cet_ucs4_to_vps_links, /* UCS-4 to char links */ + cet_ucs4_to_vps_ct, /* number of links */ + + NULL, /* hand made UCS-4 links */ + 0, /* number of extra links */ + + NULL /* for internal use */ +}; + + +/* +const int vps_ucs4_full_map[] = +{ + 0x0000, 0x0001, 0x1ea0, 0x1eac, 0x1eb6, 0x1eb8, 0x1ec6, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x1eca, 0x1ecc, 0x1ed8, 0x1ee2, 0x1ee4, 0x1ef0, 0x0016, 0x0017, + 0x0018, 0x1ef4, 0x001a, 0x001b, 0x1eaa, 0x1eee, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x00c0, 0x1ea2, 0x00c3, 0x1ea4, 0x1ea6, 0x1ea8, 0x1ecd, 0x1ed7, + 0x0102, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec7, 0x1eae, 0x1eb0, 0x1eb2, + 0x1ebe, -1, -1, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ed0, 0x1ed2, + 0x1ed4, -1, 0x00fd, 0x1ef7, 0x1ef5, 0x1eda, 0x1edc, 0x1ede, + -1, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1ee0, 0x1edb, + 0x00d9, 0x1edd, 0x1edf, 0x1ee1, 0x0168, 0x1ee8, 0x1ee3, 0x1eea, + 0x1ed5, 0x1eec, 0x1ef2, 0x1ef8, 0x00cd, 0x00cc, 0x1ed9, 0x1ec8, + 0x0128, 0x00d3, 0x1eed, 0x1eef, 0x00d2, 0x1ece, 0x00d5, 0x1ef1, + 0x1ea7, 0x00c1, 0x00c2, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, 0x0111, + 0x1ebb, 0x00c9, 0x00ca, 0x1eb9, 0x1ec9, 0x1ec5, 0x1ecb, 0x1ef9, + 0x01af, 0x1ee6, 0x1ed3, 0x1ed1, 0x00d4, 0x1ecf, 0x01a1, 0x00c8, + 0x1eeb, 0x1ee9, 0x00da, 0x0169, 0x01b0, 0x00dd, 0x1eba, -1, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x1ea3, 0x1ea1, 0x0103, -1, + 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x00ec, 0x00ed, -1, 0x0129, + 0x1eb4, 0x0110, 0x00f2, 0x00f3, 0x00f4, 0x00f5, -1, 0x01a0, + 0x1ee5, 0x00f9, 0x00fa, 0x1ee7, -1, 0x1ef6, 0x1ebc, 0x1ef3 +}; +*/ + +#endif diff --git a/cet_util.c b/cet_util.c new file mode 100644 index 000000000..ad9b68f6f --- /dev/null +++ b/cet_util.c @@ -0,0 +1,1262 @@ +/* + + Character encoding transformation - utilities + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include +#include +#include +#include +#include + +#include "defs.h" +#include "cet.h" +#include "cet_util.h" + +#if HAVE_LIBEXPAT +# include +#endif + +#define MYNAME "cet_util" + +static cet_cs_vec_t *cet_cs_vec_root = NULL; + +typedef struct cet_cs_alias_s +{ + char *name; + cet_cs_vec_t *vec; +} cet_cs_alias_t; + +static cet_cs_alias_t *cet_cs_alias; +static int cet_cs_alias_ct = 0; +static int cet_cs_vec_ct = 0; +static int cet_output = 0; + +/* %%% short hand strings transmission for main character sets %%% */ + +#include "cet/iso_8859_1.h" +char * +cet_str_utf8_to_iso8859_1(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_1); +} + +char * +cet_str_iso8859_1_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_1); +} + +#include "cet/iso_8859_15.h" + +char * +cet_str_utf8_to_iso8859_15(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_15); +} + +char * +cet_str_iso8859_15_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_15); +} + +#include "cet/ansi_x3_4_1968.h" + +char * +cet_str_utf8_to_us_ascii(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_ansi_x3_4_1968); +} + +char * +cet_str_us_ascii_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_ansi_x3_4_1968); +} + +#include "cet/cp1252.h" + +char * +cet_str_utf8_to_cp1252(const char *src) +{ + return cet_str_utf8_to_any(src, &cet_cs_vec_cp1252); +} + +char * +cet_str_cp1252_to_utf8(const char *src) +{ + return cet_str_any_to_utf8(src, &cet_cs_vec_cp1252); +} + + +/* helpers */ + +/* %%% %%% + * + * + */ +#if HAVE_LIBEXPAT +int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *xml_encoding, XML_Encoding *info) +{ + cet_cs_vec_t *cs; + int i, c, ucs4_def; + const char *encoding; + + encoding = xml_convert_to_char_string(xml_encoding); + cs = cet_find_cs_by_name(encoding); + if (cs == NULL) return XML_STATUS_ERROR; /* fatal(MYNAME ": Unknown character set \"%s\"!\n", encoding); */ + + cet_char_to_ucs4(CET_NOT_CONVERTABLE_DEFAULT, cs, &ucs4_def); + + for (i = 0; i < cs->ucs4_offset; i++) info->map[i] = i; /* equal to ascii part */ + for (i = 0; i < cs->ucs4_count; i++) /* mixed table */ + { + c = cs->ucs4_map[i]; + if (c == -1) c = ucs4_def; + info->map[i + cs->ucs4_offset] = c; + } + for (i = cs->ucs4_offset + cs->ucs4_count; i < 256; i++) info->map[i] = ucs4_def; /* non convertable trailer */ + + info->data = NULL; + info->convert = NULL; + info->release = NULL; + + cet_convert_init(CET_CHARSET_UTF8, 1); /* We do not need to transform any string */ + + if (global_opts.verbose_status > 0) + printf(MYNAME ": XML parser - encoding handler for character set \"%s\" established.\n", encoding); + + xml_free_converted_string(encoding); + return XML_STATUS_OK; +} +#endif + + +char * +cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec) +{ + char *res, *c; + const cet_cs_vec_t *cs = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + res = cet_str_uni_to_utf8(src, length); + if (cs != &cet_cs_vec_utf8) + { + c = cet_str_utf8_to_any(res, cs); + xfree(res); + res = c; + } + return res; +} + +/* %%% cet_str_any_to_any %%% + * + * -->> for use in mkshort */ + +char * +cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec) +{ + char *c0, *c1; + const cet_cs_vec_t *v_in = (src_vec != NULL ) ? src_vec : &cet_cs_vec_ansi_x3_4_1968; + const cet_cs_vec_t *v_out = (dest_vec != NULL ) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + if (src == NULL) + return NULL; + else + if ((*src == '\0') || (v_in == v_out)) return xstrdup(src); + + c0 = (v_in == &cet_cs_vec_utf8) ? xstrdup(src) : cet_str_any_to_utf8(src, v_in); + c1 = (v_out == &cet_cs_vec_utf8) ? xstrdup(c0) : cet_str_utf8_to_any(c0, v_out); + xfree(c0); + + return c1; +} + +/* %%% cet_valid_char %%% + * + * returnes 1 if convertable otherwise 0 + * + */ + +int +cet_valid_char(const char *src, const cet_cs_vec_t *vec) +{ + int value; + + const cet_cs_vec_t *v = (vec != NULL) ? vec : &cet_cs_vec_ansi_x3_4_1968; + return cet_char_to_ucs4(*src, v, &value); +} + +/* %%% include character set headers %%% */ +#if defined (CET_WANTED) +#include "cet/iso_8859_2.h" +#include "cet/cp1250.h" +#include "cet/latin_greek_1.h" +#include "cet/macintosh.h" +#include "cet/cp1250.h" +#include "cet/cp1251.h" +#include "cet/cp1252.h" +#include "cet/cp1253.h" +#include "cet/cp1254.h" +#include "cet/cp1255.h" +#include "cet/cp1256.h" +#include "cet/cp1257.h" +#include "cet/ibm437.h" +#include "cet/ibm850.h" +#include "cet/ibm851.h" +#include "cet/ibm852.h" +#include "cet/ibm855.h" +#include "cet/ibm857.h" +#include "cet/ibm860.h" +#include "cet/ibm861.h" +#include "cet/ibm862.h" +#include "cet/ibm863.h" +#include "cet/ibm864.h" +#include "cet/ibm865.h" +#include "cet/ibm868.h" +#include "cet/ibm869.h" +#include "cet/iso_8859_1.h" +#include "cet/iso_8859_10.h" +#include "cet/iso_8859_13.h" +#include "cet/iso_8859_14.h" +#include "cet/iso_8859_15.h" +#include "cet/iso_8859_2.h" +#include "cet/iso_8859_3.h" +#include "cet/iso_8859_4.h" +#include "cet/iso_8859_5.h" +#include "cet/iso_8859_6.h" +#include "cet/iso_8859_7.h" +#include "cet/iso_8859_8.h" +#include "cet/iso_8859_9.h" +#include "cet/koi8_r.h" +#include "cet/koi8_ru.h" +#include "cet/koi_8.h" +#endif + +#if CET_WANTED +#include "cet/ansi_x3_4_1968.h" +#include "cet/atarist.h" +#include "cet/baltic.h" +#include "cet/bs_4730.h" +#include "cet/bs_viewdata.h" +#include "cet/csa_z243_4_1985_1.h" +#include "cet/csa_z243_4_1985_2.h" +#include "cet/csa_z243_4_1985_gr.h" +#include "cet/csn_369103.h" +#include "cet/cwi.h" +#include "cet/dec_mcs.h" +#include "cet/din_66003.h" +#include "cet/ds_2089.h" +#include "cet/ecma_cyrillic.h" +#include "cet/es.h" +#include "cet/es2.h" +#include "cet/gb_1988_80.h" +#include "cet/gost_19768_87.h" +#include "cet/hp_roman8.h" +#include "cet/ibm037.h" +#include "cet/ibm1004.h" +#include "cet/ibm1026.h" +#include "cet/ibm1047.h" +#include "cet/ibm256.h" +#include "cet/ibm273.h" +#include "cet/ibm277.h" +#include "cet/ibm278.h" +#include "cet/ibm280.h" +#include "cet/ibm284.h" +#include "cet/ibm285.h" +#include "cet/ibm297.h" +#include "cet/ibm500.h" +#include "cet/ibm871.h" +#include "cet/ibm891.h" +#include "cet/ibm903.h" +#include "cet/ibm904.h" +#include "cet/iec_p27_1.h" +#include "cet/iso_10367_box.h" +#include "cet/iso_5427.h" +#include "cet/iso_646_irv.h" +#include "cet/iso_6937_2_25.h" +#include "cet/iso_8859_supp.h" +#include "cet/it.h" +#include "cet/jis_c6220_1969_ro.h" +#include "cet/jis_x0201.h" +#include "cet/jus_i_b1_002.h" +#include "cet/jus_i_b1_003_mac.h" +#include "cet/jus_i_b1_003_serb.h" +#include "cet/keybcs2.h" +#include "cet/koi8_u.h" +#include "cet/koi_7.h" +#include "cet/koi_8_cs2.h" +#include "cet/ksc5636.h" +#include "cet/latin_greek_1.h" +#include "cet/mac_is.h" +#include "cet/macintosh.h" +#include "cet/macintosh_ce.h" +#include "cet/msz_7795_3.h" +#include "cet/nats_dano.h" +#include "cet/nats_sefi.h" +#include "cet/nc_nc00_10.h" +#include "cet/nextstep.h" +#include "cet/nf_z_62_010.h" +#include "cet/nf_z_62_010__1973_.h" +#include "cet/ns_4551_1.h" +#include "cet/ns_4551_2.h" +#include "cet/pt.h" +#include "cet/pt2.h" +#include "cet/sami.h" +#include "cet/sen_850200_b.h" +#include "cet/sen_850200_c.h" +#include "cet/tcvn.h" +#include "cet/viscii.h" +#include "cet/vps.h" +#endif + +#ifdef DEBUG_MEM + +void +cet_check_cs(cet_cs_vec_t *vec) /* test well sorted link & extra tables */ +{ + cet_ucs4_link_t *link; + + if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) + { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_links; i++, j++) + { + if (link[i].value >= link[j].value) + { + printf(MYNAME ": checked 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-link-table unsorted !!!\n", vec->name); + } + + } + } + if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) + { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_extras; i++, j++) + { + if (link[i].value >= link[j].value) + { + printf(MYNAME ": check 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-extra-table unsorted !!!\n", vec->name); + } + + } + } +} + +#endif + +static signed int +cet_cs_alias_qsort_cb(const void *a, const void *b) +{ + const cet_cs_alias_t *va = a; + const cet_cs_alias_t *vb = b; + return case_ignore_strcmp(va->name, vb->name); +} + +static signed int +cet_cs_vec_qsort_cb(const void *a, const void *b) +{ + const cet_cs_vec_t *va = *(cet_cs_vec_t **)a; + const cet_cs_vec_t *vb = *(cet_cs_vec_t **)b; + return case_ignore_strcmp(va->name, vb->name); +} + +void +cet_register_cs(cet_cs_vec_t *vec) +{ + if (vec->next == NULL) + { + vec->next = cet_cs_vec_root; + cet_cs_vec_root = vec; + cet_cs_vec_ct++; +#ifdef DEBUG_MEM + cet_check_cs(vec); +#endif + } +} + +/* Dummy vector for our native character set */ + +const char *cet_cs_utf8_alias[] = +{ + "utf8", NULL +}; + +cet_cs_vec_t cet_cs_vec_utf8 = +{ + CET_CHARSET_UTF8, + cet_cs_utf8_alias, + NULL, /* dec */ + NULL, /* enc */ + NULL, /* link */ + 0, + 0, + NULL, /* extra */ + 0, /* extras */ + NULL +}; + +void +cet_register(void) +{ + int i, c; + + if (cet_cs_vec_root != NULL) return; + + cet_cs_vec_ct = 0; + cet_register_cs(&cet_cs_vec_utf8); /* internal place holder */ + +#ifdef cet_cs_name_ansi_x3_4_1968 +cet_register_cs(&cet_cs_vec_ansi_x3_4_1968); +#endif +#ifdef cet_cs_name_atarist +cet_register_cs(&cet_cs_vec_atarist); +#endif +#ifdef cet_cs_name_baltic +cet_register_cs(&cet_cs_vec_baltic); +#endif +#ifdef cet_cs_name_bs_4730 +cet_register_cs(&cet_cs_vec_bs_4730); +#endif +#ifdef cet_cs_name_bs_viewdata +cet_register_cs(&cet_cs_vec_bs_viewdata); +#endif +#ifdef cet_cs_name_cp1250 +cet_register_cs(&cet_cs_vec_cp1250); +#endif +#ifdef cet_cs_name_cp1251 +cet_register_cs(&cet_cs_vec_cp1251); +#endif +#ifdef cet_cs_name_cp1252 +cet_register_cs(&cet_cs_vec_cp1252); +#endif +#ifdef cet_cs_name_cp1253 +cet_register_cs(&cet_cs_vec_cp1253); +#endif +#ifdef cet_cs_name_cp1254 +cet_register_cs(&cet_cs_vec_cp1254); +#endif +#ifdef cet_cs_name_cp1255 +cet_register_cs(&cet_cs_vec_cp1255); +#endif +#ifdef cet_cs_name_cp1256 +cet_register_cs(&cet_cs_vec_cp1256); +#endif +#ifdef cet_cs_name_cp1257 +cet_register_cs(&cet_cs_vec_cp1257); +#endif +#ifdef cet_cs_name_csa_z243_4_1985_1 +cet_register_cs(&cet_cs_vec_csa_z243_4_1985_1); +#endif +#ifdef cet_cs_name_csa_z243_4_1985_2 +cet_register_cs(&cet_cs_vec_csa_z243_4_1985_2); +#endif +#ifdef cet_cs_name_csa_z243_4_1985_gr +cet_register_cs(&cet_cs_vec_csa_z243_4_1985_gr); +#endif +#ifdef cet_cs_name_csn_369103 +cet_register_cs(&cet_cs_vec_csn_369103); +#endif +#ifdef cet_cs_name_cwi +cet_register_cs(&cet_cs_vec_cwi); +#endif +#ifdef cet_cs_name_dec_mcs +cet_register_cs(&cet_cs_vec_dec_mcs); +#endif +#ifdef cet_cs_name_din_66003 +cet_register_cs(&cet_cs_vec_din_66003); +#endif +#ifdef cet_cs_name_ds_2089 +cet_register_cs(&cet_cs_vec_ds_2089); +#endif +#ifdef cet_cs_name_ecma_cyrillic +cet_register_cs(&cet_cs_vec_ecma_cyrillic); +#endif +#ifdef cet_cs_name_es +cet_register_cs(&cet_cs_vec_es); +#endif +#ifdef cet_cs_name_es2 +cet_register_cs(&cet_cs_vec_es2); +#endif +#ifdef cet_cs_name_gb_1988_80 +cet_register_cs(&cet_cs_vec_gb_1988_80); +#endif +#ifdef cet_cs_name_gost_19768_87 +cet_register_cs(&cet_cs_vec_gost_19768_87); +#endif +#ifdef cet_cs_name_hp_roman8 +cet_register_cs(&cet_cs_vec_hp_roman8); +#endif +#ifdef cet_cs_name_ibm037 +cet_register_cs(&cet_cs_vec_ibm037); +#endif +#ifdef cet_cs_name_ibm1004 +cet_register_cs(&cet_cs_vec_ibm1004); +#endif +#ifdef cet_cs_name_ibm1026 +cet_register_cs(&cet_cs_vec_ibm1026); +#endif +#ifdef cet_cs_name_ibm1047 +cet_register_cs(&cet_cs_vec_ibm1047); +#endif +#ifdef cet_cs_name_ibm256 +cet_register_cs(&cet_cs_vec_ibm256); +#endif +#ifdef cet_cs_name_ibm273 +cet_register_cs(&cet_cs_vec_ibm273); +#endif +#ifdef cet_cs_name_ibm277 +cet_register_cs(&cet_cs_vec_ibm277); +#endif +#ifdef cet_cs_name_ibm278 +cet_register_cs(&cet_cs_vec_ibm278); +#endif +#ifdef cet_cs_name_ibm280 +cet_register_cs(&cet_cs_vec_ibm280); +#endif +#ifdef cet_cs_name_ibm284 +cet_register_cs(&cet_cs_vec_ibm284); +#endif +#ifdef cet_cs_name_ibm285 +cet_register_cs(&cet_cs_vec_ibm285); +#endif +#ifdef cet_cs_name_ibm297 +cet_register_cs(&cet_cs_vec_ibm297); +#endif +#ifdef cet_cs_name_ibm437 +cet_register_cs(&cet_cs_vec_ibm437); +#endif +#ifdef cet_cs_name_ibm500 +cet_register_cs(&cet_cs_vec_ibm500); +#endif +#ifdef cet_cs_name_ibm850 +cet_register_cs(&cet_cs_vec_ibm850); +#endif +#ifdef cet_cs_name_ibm851 +cet_register_cs(&cet_cs_vec_ibm851); +#endif +#ifdef cet_cs_name_ibm852 +cet_register_cs(&cet_cs_vec_ibm852); +#endif +#ifdef cet_cs_name_ibm855 +cet_register_cs(&cet_cs_vec_ibm855); +#endif +#ifdef cet_cs_name_ibm857 +cet_register_cs(&cet_cs_vec_ibm857); +#endif +#ifdef cet_cs_name_ibm860 +cet_register_cs(&cet_cs_vec_ibm860); +#endif +#ifdef cet_cs_name_ibm861 +cet_register_cs(&cet_cs_vec_ibm861); +#endif +#ifdef cet_cs_name_ibm862 +cet_register_cs(&cet_cs_vec_ibm862); +#endif +#ifdef cet_cs_name_ibm863 +cet_register_cs(&cet_cs_vec_ibm863); +#endif +#ifdef cet_cs_name_ibm864 +cet_register_cs(&cet_cs_vec_ibm864); +#endif +#ifdef cet_cs_name_ibm865 +cet_register_cs(&cet_cs_vec_ibm865); +#endif +#ifdef cet_cs_name_ibm868 +cet_register_cs(&cet_cs_vec_ibm868); +#endif +#ifdef cet_cs_name_ibm869 +cet_register_cs(&cet_cs_vec_ibm869); +#endif +#ifdef cet_cs_name_ibm871 +cet_register_cs(&cet_cs_vec_ibm871); +#endif +#ifdef cet_cs_name_ibm891 +cet_register_cs(&cet_cs_vec_ibm891); +#endif +#ifdef cet_cs_name_ibm903 +cet_register_cs(&cet_cs_vec_ibm903); +#endif +#ifdef cet_cs_name_ibm904 +cet_register_cs(&cet_cs_vec_ibm904); +#endif +#ifdef cet_cs_name_iec_p27_1 +cet_register_cs(&cet_cs_vec_iec_p27_1); +#endif +#ifdef cet_cs_name_iso_10367_box +cet_register_cs(&cet_cs_vec_iso_10367_box); +#endif +#ifdef cet_cs_name_iso_5427 +cet_register_cs(&cet_cs_vec_iso_5427); +#endif +#ifdef cet_cs_name_iso_646_irv +cet_register_cs(&cet_cs_vec_iso_646_irv); +#endif +#ifdef cet_cs_name_iso_6937_2_25 +cet_register_cs(&cet_cs_vec_iso_6937_2_25); +#endif +#ifdef cet_cs_name_iso_8859_1 +cet_register_cs(&cet_cs_vec_iso_8859_1); +#endif +#ifdef cet_cs_name_iso_8859_10 +cet_register_cs(&cet_cs_vec_iso_8859_10); +#endif +#ifdef cet_cs_name_iso_8859_13 +cet_register_cs(&cet_cs_vec_iso_8859_13); +#endif +#ifdef cet_cs_name_iso_8859_14 +cet_register_cs(&cet_cs_vec_iso_8859_14); +#endif +#ifdef cet_cs_name_iso_8859_15 +cet_register_cs(&cet_cs_vec_iso_8859_15); +#endif +#ifdef cet_cs_name_iso_8859_2 +cet_register_cs(&cet_cs_vec_iso_8859_2); +#endif +#ifdef cet_cs_name_iso_8859_3 +cet_register_cs(&cet_cs_vec_iso_8859_3); +#endif +#ifdef cet_cs_name_iso_8859_4 +cet_register_cs(&cet_cs_vec_iso_8859_4); +#endif +#ifdef cet_cs_name_iso_8859_5 +cet_register_cs(&cet_cs_vec_iso_8859_5); +#endif +#ifdef cet_cs_name_iso_8859_6 +cet_register_cs(&cet_cs_vec_iso_8859_6); +#endif +#ifdef cet_cs_name_iso_8859_7 +cet_register_cs(&cet_cs_vec_iso_8859_7); +#endif +#ifdef cet_cs_name_iso_8859_8 +cet_register_cs(&cet_cs_vec_iso_8859_8); +#endif +#ifdef cet_cs_name_iso_8859_9 +cet_register_cs(&cet_cs_vec_iso_8859_9); +#endif +#ifdef cet_cs_name_iso_8859_supp +cet_register_cs(&cet_cs_vec_iso_8859_supp); +#endif +#ifdef cet_cs_name_it +cet_register_cs(&cet_cs_vec_it); +#endif +#ifdef cet_cs_name_jis_c6220_1969_ro +cet_register_cs(&cet_cs_vec_jis_c6220_1969_ro); +#endif +#ifdef cet_cs_name_jis_x0201 +cet_register_cs(&cet_cs_vec_jis_x0201); +#endif +#ifdef cet_cs_name_jus_i_b1_002 +cet_register_cs(&cet_cs_vec_jus_i_b1_002); +#endif +#ifdef cet_cs_name_jus_i_b1_003_mac +cet_register_cs(&cet_cs_vec_jus_i_b1_003_mac); +#endif +#ifdef cet_cs_name_jus_i_b1_003_serb +cet_register_cs(&cet_cs_vec_jus_i_b1_003_serb); +#endif +#ifdef cet_cs_name_keybcs2 +cet_register_cs(&cet_cs_vec_keybcs2); +#endif +#ifdef cet_cs_name_koi8_r +cet_register_cs(&cet_cs_vec_koi8_r); +#endif +#ifdef cet_cs_name_koi8_ru +cet_register_cs(&cet_cs_vec_koi8_ru); +#endif +#ifdef cet_cs_name_koi8_u +cet_register_cs(&cet_cs_vec_koi8_u); +#endif +#ifdef cet_cs_name_koi_7 +cet_register_cs(&cet_cs_vec_koi_7); +#endif +#ifdef cet_cs_name_koi_8 +cet_register_cs(&cet_cs_vec_koi_8); +#endif +#ifdef cet_cs_name_koi_8_cs2 +cet_register_cs(&cet_cs_vec_koi_8_cs2); +#endif +#ifdef cet_cs_name_ksc5636 +cet_register_cs(&cet_cs_vec_ksc5636); +#endif +#ifdef cet_cs_name_latin_greek_1 +cet_register_cs(&cet_cs_vec_latin_greek_1); +#endif +#ifdef cet_cs_name_mac_is +cet_register_cs(&cet_cs_vec_mac_is); +#endif +#ifdef cet_cs_name_macintosh +cet_register_cs(&cet_cs_vec_macintosh); +#endif +#ifdef cet_cs_name_macintosh_ce +cet_register_cs(&cet_cs_vec_macintosh_ce); +#endif +#ifdef cet_cs_name_msz_7795_3 +cet_register_cs(&cet_cs_vec_msz_7795_3); +#endif +#ifdef cet_cs_name_nats_dano +cet_register_cs(&cet_cs_vec_nats_dano); +#endif +#ifdef cet_cs_name_nats_sefi +cet_register_cs(&cet_cs_vec_nats_sefi); +#endif +#ifdef cet_cs_name_nc_nc00_10 +cet_register_cs(&cet_cs_vec_nc_nc00_10); +#endif +#ifdef cet_cs_name_nextstep +cet_register_cs(&cet_cs_vec_nextstep); +#endif +#ifdef cet_cs_name_nf_z_62_010 +cet_register_cs(&cet_cs_vec_nf_z_62_010); +#endif +#ifdef cet_cs_name_nf_z_62_010__1973_ +cet_register_cs(&cet_cs_vec_nf_z_62_010__1973_); +#endif +#ifdef cet_cs_name_ns_4551_1 +cet_register_cs(&cet_cs_vec_ns_4551_1); +#endif +#ifdef cet_cs_name_ns_4551_2 +cet_register_cs(&cet_cs_vec_ns_4551_2); +#endif +#ifdef cet_cs_name_pt +cet_register_cs(&cet_cs_vec_pt); +#endif +#ifdef cet_cs_name_pt2 +cet_register_cs(&cet_cs_vec_pt2); +#endif +#ifdef cet_cs_name_sami +cet_register_cs(&cet_cs_vec_sami); +#endif +#ifdef cet_cs_name_sen_850200_b +cet_register_cs(&cet_cs_vec_sen_850200_b); +#endif +#ifdef cet_cs_name_sen_850200_c +cet_register_cs(&cet_cs_vec_sen_850200_c); +#endif +#ifdef cet_cs_name_tcvn +cet_register_cs(&cet_cs_vec_tcvn); +#endif +#ifdef cet_cs_name_viscii +cet_register_cs(&cet_cs_vec_viscii); +#endif +#ifdef cet_cs_name_vps +cet_register_cs(&cet_cs_vec_vps); +#endif + + if ( cet_cs_vec_ct > 0) + { + cet_cs_vec_t *p; + cet_cs_alias_t *list; + c = 0; + + /* enumerate count of all names and aliases */ + + for (p = cet_cs_vec_root; p != NULL; p = p->next) + { + c++; + if (p->alias != NULL) + { + char **a = (char **)p->alias; + while ((*a) != NULL) + { + a++; + c++; + } + } + } + /* create name to vec table */ + + list = xcalloc(c, sizeof(*list)); + i = 0; + for (p = cet_cs_vec_root; p != NULL; p = p->next) + { + if (p->alias != NULL) + { + char **a = (char **)p->alias; + + list[i].name = xstrdup(p->name); + list[i].vec = p; + i++; + while (*a != NULL) + { + list[i].name = xstrdup(*a); + list[i].vec = p; + i++; + a++; + } + } + } + qsort(list, c, sizeof(*list), cet_cs_alias_qsort_cb); + cet_cs_alias = list; + cet_cs_alias_ct = c; +#ifdef CET_DEBUG + printf("We have registered %d character sets with %d aliases\n", cet_cs_vec_ct, cet_cs_alias_ct); +#endif + } +} + +cet_cs_vec_t * +cet_find_cs_by_name(const char *name) +{ + int i, j; + + cet_register(); + + if (cet_cs_alias == NULL) return NULL; + + i = 0; + j = cet_cs_alias_ct - 1; + + while (i <= j) + { + int a, x; + cet_cs_alias_t *n; + + a = (i + j) >> 1; + n = &cet_cs_alias[a]; + x = case_ignore_strcmp(name, n->name); + if (x == 0) return n->vec; + else if (x < 0) j = a - 1; + else i = a + 1; + } + return NULL; +} + +void +cet_deregister(void) +{ + int i; + int j = cet_cs_alias_ct; + cet_cs_alias_t *p = cet_cs_alias; + + if (p == NULL) return; + + cet_cs_alias_ct = 0; + cet_cs_alias = NULL; + + for (i = 0; i < j; i++) + xfree(p[i].name); + xfree(p); +} + +/* gpsbabel additions */ + +int +cet_validate_cs(const char *cs, cet_cs_vec_t **vec, char **cs_name) +{ + cet_cs_vec_t *v; + + if ((cs == NULL) || (strlen(cs) == 0)) /* set default us-ascii */ + { + *vec = &cet_cs_vec_ansi_x3_4_1968; + *cs_name = xstrdup(CET_CHARSET_ASCII); + return 1; + } + + v = cet_find_cs_by_name(cs); + if (v != NULL) + { + *cs_name = strupper(xstrdup(v->name)); + *vec = v; + return 1; + } + else + { + *cs_name = NULL; + *vec = NULL; + return 0; + } +} + +void +cet_convert_deinit(void) +{ + if (global_opts.charset_name != NULL) xfree(global_opts.charset_name); + global_opts.charset = NULL; + global_opts.charset_name = NULL; +} + +void +cet_convert_init(const char *cs_name, const int force) +{ + if ((force != 0) || (global_opts.charset == NULL)) + { + cet_convert_deinit(); + if (0 == cet_validate_cs(cs_name, &global_opts.charset, &global_opts.charset_name)) + fatal("Unsupported character set \"%s\"!\n", cs_name); + } +} + +/* -------------------------------------------------------------------- */ +/* %%% complete data strings transformation %%% */ +/* -------------------------------------------------------------------- */ + +static char * (*converter) (const char *) = NULL; + +/* two converters */ + +static char * +cet_convert_to_utf8(const char *str) +{ + return cet_str_any_to_utf8(str, global_opts.charset); +} + +static char * +cet_convert_from_utf8(const char *str) +{ + return cet_str_utf8_to_any(str, global_opts.charset); +} + +/* cet_convert_string: internal used within cet_convert_strings process */ + +char * +cet_convert_string(char *str) +{ + char *res; + + if (str == NULL) return NULL; /* return origin if empty or NULL */ + else if (*str == '\0') return str; + + res = converter(str); + xfree(str); + return res; +} + +/* cet_convert_waypt: internal used within cet_convert_strings process */ + +static void +cet_convert_waypt(const waypoint *wpt) +{ + waypoint *w = (waypoint *)wpt; + format_specific_data *fs; + + if ((cet_output == 0) && (w->wpt_flags.cet_converted != 0)) return; + + w->wpt_flags.cet_converted = 1; + + w->shortname = cet_convert_string(wpt->shortname); + w->description = cet_convert_string(wpt->description); + w->notes = cet_convert_string(wpt->notes); + w->url = cet_convert_string(wpt->url); + w->url_link_text = cet_convert_string(wpt->url_link_text); + + fs = wpt->fs; + while (fs != NULL) + { + if (fs->convert != NULL) + fs->convert(fs); + fs = fs->next; + } +} + +/* cet_convert_route_hdr: internal used within cet_convert_strings process */ + +static void +cet_convert_route_hdr(const route_head *route) +{ + route_head *rte = (route_head *)route; + + if ((cet_output == 0) && (rte->cet_converted != 0)) return; + + rte->cet_converted = 1; + + rte->rte_name = cet_convert_string(route->rte_name); + rte->rte_desc = cet_convert_string(route->rte_desc); + rte->rte_url = cet_convert_string(route->rte_url); +} + +/* cet_convert_route_tlr: internal used within cet_convert_strings process */ + +static void +cet_convert_route_tlr(const route_head *route) +{ +} + +/* %%% cet_convert_strings (public) %%% + * + * - Convert all well known strings of GPS data from or to UTF-8 - + * + * !!! One of "source" or "target" must be internal cet_cs_vec_utf8 or NULL !!! */ + +void +cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format) +{ + char *cs_name_from, *cs_name_to; + + converter = NULL; + + if ((source == NULL) || (source == &cet_cs_vec_utf8)) + { + if ((target == NULL) || (target == &cet_cs_vec_utf8)) return; /* Nothing to do */ + + cet_output = 1; + + converter = cet_convert_from_utf8; + cs_name_from = (char *)cet_cs_vec_utf8.name; + cs_name_to = (char *)target->name; + } + else + { + if ((target != NULL) && (target != &cet_cs_vec_utf8)) + fatal(MYNAME ": Internal error!\n"); + converter = cet_convert_to_utf8; + cs_name_to = (char *)cet_cs_vec_utf8.name; + cs_name_from = (char *)source->name; + } + + if (global_opts.debug_level > 0) + printf(MYNAME ": Converting from \"%s\" to \"%s\"", cs_name_from, cs_name_to); + + waypt_disp_all(cet_convert_waypt); + route_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + track_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + + cet_output = 0; + + if (global_opts.debug_level > 0) + printf(", done.\n"); +} + +/* %%% cet_disp_character_set_names %%% + * + * - Put all character set names and aliases to "FILE" - */ + +void +cet_disp_character_set_names(FILE *fout) +{ + int i, c, ac; + cet_cs_vec_t *vec; + cet_cs_vec_t **list; + + if (cet_cs_alias_ct == 0) return; + + c = 0; + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) c++; + + if (cet_cs_vec_ct != c) + fatal(MYNAME ": internal error \"%s\"!\n", "cet_disp_character_set_names"); + + list = (cet_cs_vec_t **)xcalloc(c, sizeof(*list)); + + i = 0; /* fill the list */ + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) list[i++] = vec; + qsort(list, c, sizeof(*list), cet_cs_vec_qsort_cb); /* sort list by name */ + + ac = 0; + + fprintf(fout, "GPSbabel builtin character sets: (-c option)\n"); + for (i = 0; i < c; i++) + { + char **a; + + vec = list[i]; + fprintf(fout, "\n* %s", vec->name); + + a = (char **)vec->alias; + if (a != NULL) + { + int column = 0; + int alias = 0; + + while (*a != NULL) + { + if (case_ignore_strcmp(*a, vec->name) != 0) + { + ac++; + fprintf(fout, "%s%s%s", + (alias++ > 0) ? ", " : "", + (column++ % 6 == 0) ? "\n\t" : "", + *a); + } + a++; + } + } + } + fprintf(fout, "\n\n"); + fprintf(fout, "We have %d builtin character sets with %d aliases!\n", c, ac); + xfree(list); +} + +/* %%% cet_fprintf / cet_vfprintf %%% + * + * - print any special hard-coded characters from inside a module - */ + +int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...) +{ + char buff[128]; + int res, ct; + va_list args; + char *cout = buff; + + va_start(args, fmt); + ct = vsnprintf(buff, sizeof(buff), fmt, args); + va_end(args); + + if (ct >= (int)sizeof(buff)) { + cout = xmalloc(ct + 1); + va_start(args, fmt); + vsnprintf(cout, ct + 1, fmt, args); + va_end(args); + } + + if (global_opts.charset != src_vec) + { + if (src_vec != &cet_cs_vec_utf8) { + char *ctemp = cet_str_any_to_utf8(cout, src_vec); + if (cout != buff) xfree(cout); + cout = ctemp; + } + if (global_opts.charset != &cet_cs_vec_utf8) { + char *ctemp = cet_str_utf8_to_any(cout, global_opts.charset); + if (cout != buff) xfree(cout); + cout = ctemp; + } + } + + res = gbfprintf(stream, "%s", cout); + if (cout != buff) xfree(cout); + + return res; +} + +/* + * 'str' points to an array of XML_Chars which may be UNICODE16 + * words in native endianness. + */ + +const char *xml_convert_to_char_string_n(const XML_Char *src, int *n) +{ +#ifdef XML_UNICODE + char *utf8; + char *utf8b; + int i, j; + + /* + * '*n' is the number of source bytes. + * Walk over that, converting each character and + * discarding it, but tallying 'i' as the number of + * bytes in the destination string. + */ + i = 0; + for (j = 0; j < *n; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* Update output byte count in caller. */ + *n = i; + + /* Appropriately size (not zero terminated) buffer */ + utf8 = utf8b = xmalloc(i); + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + + return utf8b; +#else + return src; +#endif +} + +/* + * 'str' points to NULL terminated string of XML_Chars which + * may be UNICODE16 words in native endianness. + */ + +const char *xml_convert_to_char_string(const XML_Char *src) +{ +#ifdef XML_UNICODE + char *utf8; + char *utf8b; + int i, j; + const XML_Char *in = src; + + /* Walk source array until we find source terminator */ + i = 0; + for (j = 0; src[j]; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* We return a NUL terminated string. */ + utf8 = utf8b = xmalloc(i + 1); + in = src; + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + *utf8 = '\0'; + + return utf8b; + +#else + return src; +#endif +} + + +void xml_free_converted_string(const char *str) +{ +#ifdef XML_UNICODE + xfree((void *) str); +#endif +} + +const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) +{ +#ifdef XML_UNICODE + // First count size of array + int size = 0; + int i; + const XML_Char **ptr; + const char **char_attrs; + + if (xml_attr == NULL) + return NULL; + + for (ptr = xml_attr; *ptr != NULL; ++ptr) + ++size; + + // Allocate space + char_attrs = xmalloc((size + 1) * sizeof(char *)); + + // Duplicate strings + for (i = 0; i < size; ++i) + char_attrs[i] = xml_convert_to_char_string(xml_attr[i]); + char_attrs[size] = NULL; + + return char_attrs; +#else + return xml_attr; +#endif +} + +void xml_free_converted_attrs(const char **attr) +{ +#ifdef XML_UNICODE + while (attr != NULL && *attr != NULL) { + xfree((void *)*attr); + ++attr; + } +#endif +} diff --git a/cet_util.h b/cet_util.h new file mode 100644 index 000000000..9a010a459 --- /dev/null +++ b/cet_util.h @@ -0,0 +1,133 @@ +/* + + Character encoding transformation - utilities header + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#ifndef CET_UTIL_H +#define CET_UTIL_H + +#include +#include +#include "config.h" + +#if HAVE_LIBEXPAT +# include +#else +typedef char XML_Char; +#endif + +#include "cet.h" + +cet_cs_vec_t *cet_find_cs_by_name(const char *name); +void cet_register(void); +void cet_deregister(void); + +/* short hand transmissions */ + +char *cet_str_utf8_to_cp1252(const char *src); +char *cet_str_cp1252_to_utf8(const char *src); +extern cet_cs_vec_t cet_cs_vec_cp1252; + +char *cet_str_iso8859_1_to_utf8(const char *src); +char *cet_str_utf8_to_iso8859_1(const char *src); +extern cet_cs_vec_t cet_cs_vec_iso8859_1; + +char *cet_str_iso8859_15_to_utf8(const char *src); +char *cet_str_utf8_to_iso8859_15(const char *src); +extern const cet_cs_vec_t cet_cs_vec_iso8859_15; + +char *cet_str_utf8_to_us_ascii(const char *src); +char *cet_str_us_ascii_to_utf8(const char *src); +extern cet_cs_vec_t cet_cs_vec_ansi_x3_4_1968; + + +extern cet_cs_vec_t cet_cs_vec_utf8; + + +/* Missing defines in older expat libraries | CET-REVIEW */ + +/* Taken from expat_external.h (Expat 1.95.7) */ + +#ifndef XML_STATUS_OK +# define XML_STATUS_OK 1 +#endif +#ifndef XML_STATUS_ERROR +# define XML_STATUS_ERROR 0 +#endif + + +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + +#if HAVE_LIBEXPAT +int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *encoding, XML_Encoding *info); +#endif + +/* helpers */ + +char *cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec); +char *cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec); +int cet_valid_char(const char *src, const cet_cs_vec_t *vec); + +int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...); + +/* cet_convert_string: !!! ONLY VALID WITHIN 'cet_convert_strings' process !!! */ +char *cet_convert_string(char *str); + +/* gpsbabel extensions */ + +void cet_convert_init(const char *cs_name, const int force); +void cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format); +void cet_convert_deinit(void); + +void cet_disp_character_set_names(FILE *fout); + +/* + * Conversion from XML_Char string to char string. If XML_Char is the + * same as char, these routines do nothing. If XML_Char is a wide + * character, xml_convert_to_char_string converts the string to a + * newly allocated char string, and xml_free_converted_string frees + * it. + */ + +const char *xml_convert_to_char_string_n(const XML_Char *str, int *nbytes); +const char *xml_convert_to_char_string(const XML_Char *str); +void xml_free_converted_string(const char *str); + +const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr); +void xml_free_converted_attrs(const char **attr); + +#endif diff --git a/cetus.c b/cetus.c index ba44ed1f8..406824e02 100644 --- a/cetus.c +++ b/cetus.c @@ -29,6 +29,7 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" # @@ -139,19 +140,20 @@ typedef struct cetus_track_point_s static FILE *file_in; static FILE *file_out; static const char *out_fname; -struct pdb *opdb; -struct pdb_record *opdb_rec; -static void *mkshort_wr_handle; +static struct pdb *opdb; +static struct pdb_record *opdb_rec; +static short_handle mkshort_wr_handle; static char *dbname = NULL; static char *appendicon = NULL; static arglist_t cetus_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING }, - {"appendicon", &appendicon, "Append icon_descr to description.", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0 } + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX }, + {"appendicon", &appendicon, "Append icon_descr to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static waypoint * @@ -247,7 +249,7 @@ read_tracks(const struct pdb *pdb) tm.tm_mday = head->day; tm.tm_mon = head->month - 1; tm.tm_year = head->year + 100; - basetime = mktime(&tm); + basetime = mkgmtime(&tm); break; case 1: /* first part of description */ @@ -265,7 +267,7 @@ read_tracks(const struct pdb *pdb) wpt = read_track_point((cetus_track_point_t *)c, basetime); if (wpt != NULL) { - route_add_wpt(track, wpt); + track_add_wpt(track, wpt); points++; /* Did we run over midnight ? */ @@ -343,7 +345,7 @@ read_waypts(const struct pdb *pdb) tm.tm_mon = rec->mon - 1; tm.tm_year = be_read16(&rec->year) - 1900; - wpt_tmp->creation_time = mktime(&tm); + wpt_tmp->creation_time = mkgmtime(&tm); } @@ -477,7 +479,7 @@ cetus_writewpt(const waypoint *wpt) vdata = (char *)rec + sizeof(*rec); if ( wpt->shortname ) { - char *sn = str_utf8_to_cp1252(wpt->shortname); + char *sn = xstrdup(wpt->shortname); strncpy( vdata, sn, 16 ); vdata[15] = '\0'; xfree(sn); @@ -490,7 +492,7 @@ cetus_writewpt(const waypoint *wpt) if (wpt->gc_data.desc_short.utfstring) { char *stripped_html = strip_html(&wpt->gc_data.desc_short); desc_short = xstrdup("\n\n"); - desc_short = xstrappend(desc_short, str_utf8_to_cp1252(stripped_html)); + desc_short = xstrappend(desc_short, xstrdup(stripped_html)); xfree(stripped_html); } else { desc_short = xstrdup(""); @@ -499,13 +501,13 @@ cetus_writewpt(const waypoint *wpt) if (wpt->gc_data.desc_long.utfstring) { char *stripped_html = strip_html(&wpt->gc_data.desc_long); desc_long = xstrdup("\n\n"); - desc_long = xstrappend(desc_long, str_utf8_to_cp1252(stripped_html)); + desc_long = xstrappend(desc_long, xstrdup(stripped_html)); xfree(stripped_html); } else { desc_long = xstrdup(""); } - desc = wpt->description ? str_utf8_to_cp1252(wpt->description) : + desc = wpt->description ? xstrdup(wpt->description) : xstrdup(""); snprintf(vdata, DESCSZ, "%s%s%s", @@ -529,7 +531,7 @@ cetus_writewpt(const waypoint *wpt) vdata += strlen( vdata ) + 1; if (wpt->gc_data.hint) { - char *hint = str_utf8_to_cp1252(wpt->gc_data.hint); + char *hint = xstrdup(wpt->gc_data.hint); rec->type = WptCache; strncpy( vdata, hint, NOTESZ + 1 ) ; xfree(hint); @@ -623,7 +625,7 @@ data_write(void) pdb_Write(opdb, fileno(file_out)); xfree(htable); - mkshort_del_handle(mkshort_wr_handle); + mkshort_del_handle(&mkshort_wr_handle); } @@ -638,4 +640,6 @@ ff_vecs_t cetus_vecs = { data_write, NULL, cetus_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; +#endif diff --git a/chkdoc b/chkdoc index f95844f6b..f16444efd 100644 --- a/chkdoc +++ b/chkdoc @@ -4,6 +4,8 @@ checkit() { export ECODE TYPE=$1 STY=$2 + DIR=${2}s + if ! grep -q $TYPE ~/src/babelweb/capabilities.html ~/src/babelweb/capabilities.inc then echo $STY $TYPE is not documented in capabilities.html. @@ -15,10 +17,11 @@ checkit() { echo $STY $TYPE is not documented in changes.html. ECODE=1 fi - - if ! grep -qi "^ $TYPE$" ~/src/babelweb/README + + DOCF=xmldoc/$DIR/${TYPE}.xml + if ! test -f $DOCF ; then - echo $STY $TYPE is not documented in README. + echo $STY $TYPE is not documented in $DOCF ECODE=1 fi diff --git a/coastexp.c b/coastexp.c index 81b2a19eb..3af5b093d 100644 --- a/coastexp.c +++ b/coastexp.c @@ -18,17 +18,19 @@ */ #include "defs.h" -#if !NO_EXPAT -#include "xmlgeneric.h" -#include -static XML_Parser psr; +#if HAVE_LIBEXPAT +# include "xmlgeneric.h" +# include + static XML_Parser psr; #endif + #include +#include "cet_util.h" #include "uuid.h" -FILE *fd; -FILE *ofd; +static FILE *fd; +static FILE *ofd; #define MYNAME "coastexp" #define MY_CBUF 4096 @@ -36,18 +38,6 @@ FILE *ofd; #define MY_TBUF 64 #define MY_XBUF 128 -#if NO_EXPAT -void -ce_rd_init(const char *fname) -{ - fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); -} - -void -ce_read(void) -{ -} -#else static char *element; // Current element being parsed static char *cdatastr; // Current XML character data being built up (until a ) @@ -126,11 +116,28 @@ ce_free_route(ce_route *route) // Don't free the waypoint since this is done elsewhere } +#if !HAVE_LIBEXPAT +void +ce_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); +} + +void +ce_read(void) +{ +} +#else + /* Start processing an XML item */ static void -ce_start(void *data, const char *el, const char **attr) +ce_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { + const char *el = xml_convert_to_char_string(xml_el); const char **ap; + const char **attr; + + attr = xml_convert_attrs_to_char_string(xml_attr); strcpy(element, el); if (0 == strcmp(el, "Route")) { inRoute = 1; @@ -162,12 +169,15 @@ ce_start(void *data, const char *el, const char **attr) } } } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } /* Finish processing an XML item */ static void -ce_end(void *data, const char *el) +ce_end(void *data, const XML_Char *xml_el) { + const char *el = xml_convert_to_char_string(xml_el); if (0 == strcmp(el, "Route")) { if (!doing_rtes) ce_free_route(currentRoute); @@ -175,12 +185,15 @@ ce_end(void *data, const char *el) } else if (0 == strcmp(el, "Mark")) inMark = 0; + xml_free_converted_string(el); } /* Process some XML character data for the current item */ static void -ce_cdata(void *dta, const XML_Char *s, int len) +ce_cdata(void *dta, const XML_Char *xml_s, int len) { + const char *origs = xml_convert_to_char_string_n(xml_s, &len); + const char *s = origs; if (*s != '\n') { char *edatastr; // We buffer up characters in 'cdatastr' until a single is received @@ -291,6 +304,8 @@ ce_cdata(void *dta, const XML_Char *s, int len) // Start building a new string since we are done with this one cdatastr[0] = '\0'; } + + xml_free_converted_string(origs); } /* Set up reading the CE input file */ @@ -306,6 +321,7 @@ ce_rd_init(const char *fname) fatal(MYNAME ":Cannot create XML parser\n"); } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); XML_SetElementHandler(psr, ce_start, ce_end); cdatastr = xcalloc(MY_CBUF,1); element = xcalloc(MY_CBUF,1); @@ -322,7 +338,7 @@ ce_read(void) while ((len = fread(buf, 1, sizeof(buf), fd))) { if (!XML_Parse(psr, buf, len, feof(fd))) { fatal(MYNAME ":Parse error at %d: %s\n", - XML_GetCurrentLineNumber(psr), + (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); } } @@ -512,7 +528,9 @@ static char * ce_gen_uuid(void) { uuid_t uu; - uuid_generate(uu); + + memset(&uu, 0, sizeof(uu)); + gb_uuid_generate(uu); sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); @@ -634,4 +652,5 @@ ff_vecs_t coastexp_vecs = { ce_write, NULL, NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/coldsync/Makefile b/coldsync/Makefile index c2d54597a..e69de29bb 100644 --- a/coldsync/Makefile +++ b/coldsync/Makefile @@ -1,38 +0,0 @@ -# $Id: Makefile,v 1.1 2002/08/16 06:13:10 robertl Exp $ - -TOP = .. -SUBDIR = libpdb - -LIBNAME = pdb -SHLIB_MAJOR = 0 -SHLIB_MINOR = 0 - -LIBSRCS = pdb.c util.c -LIBOBJS = ${LIBSRCS:.c=.o} -SHLIBOBJS = ${LIBSRCS:.c=.So} - -CLEAN = ${LIBOBJS} ${SHLIBOBJS} ${LIBRARY} \ - *.ln *.bak *~ core *.core .depend -DISTCLEAN = -SPOTLESS = - -DISTFILES = Makefile ${LIBSRCS} - -OTHERTAGFILES = ${LIBSRCS} - -include ${TOP}/Make.rules - -depend:: - ${MKDEP} ${CPPFLAGS} ${LIBSRCS} - -all:: ${LIBRARY} - -# It might be a good idea later on to install the library, so that -# people can write other programs that communicate with the Palm, but -# not just yet. -# install:: - -# This is for Emacs's benefit: -# Local Variables: *** -# fill-column: 75 *** -# End: *** diff --git a/coldsync/Makefile.in b/coldsync/Makefile.in new file mode 100644 index 000000000..e69de29bb diff --git a/coldsync/config.h b/coldsync/cs-config.h similarity index 100% rename from coldsync/config.h rename to coldsync/cs-config.h diff --git a/coldsync/palm.h b/coldsync/palm.h index 0bac9ec0c..2b111d532 100644 --- a/coldsync/palm.h +++ b/coldsync/palm.h @@ -5,18 +5,20 @@ * You may distribute this file under the terms of the Artistic * License, as specified in the README file. * - * $Id: palm.h,v 1.1 2002/08/16 06:13:10 robertl Exp $ + * $Id: palm.h,v 1.2 2005/10/24 18:26:30 robertl Exp $ */ #ifndef _palm_h_ #define _palm_h_ +#include "../gbtypes.h" + /* Convenience types */ typedef signed char byte; /* Signed 8-bit quantity */ typedef unsigned char ubyte; /* Unsigned 8-bit quantity */ -typedef signed short word; /* Signed 16-bit quantity */ -typedef unsigned short uword; /* Unsigned 16-bit quantity */ -typedef signed long dword; /* Signed 32-bit quantity */ -typedef unsigned long udword; /* Unsigned 32-bit quantity */ +typedef gbint16 word; /* Signed 16-bit quantity */ +typedef gbuint16 uword; /* Unsigned 16-bit quantity */ +typedef gbint32 dword; /* Signed 32-bit quantity */ +typedef gbuint32 udword; /* Unsigned 32-bit quantity */ typedef udword chunkID; /* Those IDs made up of four * characters stuck together into a diff --git a/coldsync/pdb.c b/coldsync/pdb.c index 041b7f12c..161efc64c 100644 --- a/coldsync/pdb.c +++ b/coldsync/pdb.c @@ -6,7 +6,7 @@ * You may distribute this file under the terms of the Artistic * License, as specified in the README file. * - * $Id: pdb.c,v 1.7 2005/03/18 03:56:35 robertl Exp $ + * $Id: pdb.c,v 1.12 2006/07/13 03:27:53 robertl Exp $ */ /* XXX - The way zero-length records are handled is a bit of a kludge. They * shouldn't normally exist, with the exception of expunged records. But, @@ -21,8 +21,10 @@ * with them. * Debugging messages should go to 'FILE *pdb_logfile'. */ - #include "config.h" +#if PDBFMTS_ENABLED + +#include "cs-config.h" #include #include /* For open() */ #include @@ -35,6 +37,10 @@ */ #if defined (__WIN32__) #include +#define lseek _lseek +#define write _write +#define read _read +#define close _close #else #include #endif @@ -555,7 +561,7 @@ pdb_Write(const struct pdb *db, _("\"%.*s\" record 0x%08lx has " "length 0.\n"), PDB_DBNAMELEN, db->name, - rec->id); + (unsigned long) rec->id); } put_udword(&wptr, offset); @@ -966,7 +972,7 @@ new_Record(const ubyte flags, fprintf(stderr, "new_Record: Creating new record:\n"); fprintf(stderr, "\tflags == 0x%02x\n", flags); fprintf(stderr, "\tcategory == 0x%02x\n", category); - fprintf(stderr, "\tid == 0x%08lx\n", id); + fprintf(stderr, "\tid == 0x%08lx\n", (unsigned long) id); fprintf(stderr, "\tlen == %d\n", len); debug_dump(stderr, "NEW", data, len); } @@ -1032,12 +1038,12 @@ new_Resource(const udword type, { fprintf(stderr, "new_Resource: Creating new resource:\n"); fprintf(stderr, "\ttype == 0x%08lx (%c%c%c%c)\n", - type, + (unsigned long) type, (int) ((type >> 24) & 0xff), (int) ((type >> 16) & 0xff), (int) ((type >> 8) & 0xff), (int) (type & 0xff)); - fprintf(stderr, "\tid == 0x%04x\n", id); + fprintf(stderr, "\tid == 0x%04x\n", (unsigned) id); fprintf(stderr, "\tlen == %d\n", len); debug_dump(stderr, "NEW", data, len); } @@ -1266,32 +1272,33 @@ pdb_LoadHeader(int fd, fprintf(stderr, "\n"); fprintf(stderr, "\tversion: %u\n", db->version); t = db->ctime - EPOCH_1904; - fprintf(stderr, "\tctime: %lu %s", db->ctime, + fprintf(stderr, "\tctime: %lu %s", (unsigned long) db->ctime, ctime(&t)); t = db->mtime - EPOCH_1904; - fprintf(stderr, "\tmtime: %lu %s", db->mtime, + fprintf(stderr, "\tmtime: %lu %s", (unsigned long) db->mtime, ctime(&t)); t = db->baktime - EPOCH_1904; - fprintf(stderr, "\tbaktime: %lu %s", db->baktime, + fprintf(stderr, "\tbaktime: %lu %s", (unsigned long) db->baktime, ctime(&t)); - fprintf(stderr, "\tmodnum: %ld\n", db->modnum); + fprintf(stderr, "\tmodnum: %lu\n", (unsigned long) db->modnum); fprintf(stderr, "\tappinfo_offset: 0x%08lx\n", - db->appinfo_offset); + (unsigned long) db->appinfo_offset); fprintf(stderr, "\tsortinfo_offset: 0x%08lx\n", - db->sortinfo_offset); + (unsigned long) db->sortinfo_offset); fprintf(stderr, "\ttype: '%c%c%c%c' (0x%08lx)\n", (char) (db->type >> 24) & 0xff, (char) (db->type >> 16) & 0xff, (char) (db->type >> 8) & 0xff, (char) db->type & 0xff, - db->type); + (unsigned long) db->type); fprintf(stderr, "\tcreator: '%c%c%c%c' (0x%08lx)\n", (char) (db->creator >> 24) & 0xff, (char) (db->creator >> 16) & 0xff, (char) (db->creator >> 8) & 0xff, (char) db->creator & 0xff, - db->creator); - fprintf(stderr, "\tuniqueIDseed: %ld\n", db->uniqueIDseed); + (unsigned long) db->creator); + fprintf(stderr, "\tuniqueIDseed: %lu\n", + (unsigned long) db->uniqueIDseed); } return 0; /* Success */ @@ -1323,7 +1330,7 @@ pdb_LoadRecListHeader(int fd, PDB_TRACE(6) { - fprintf(stderr, "\tnextID: %ld\n", db->next_reclistID); + fprintf(stderr, "\tnextID: %ld\n", (long) db->next_reclistID); fprintf(stderr, "\tlen: %u\n", db->numrecs); } @@ -1397,9 +1404,9 @@ pdb_LoadRsrcIndex(int fd, (char) (rsrc->type >> 16) & 0xff, (char) (rsrc->type >> 8) & 0xff, (char) rsrc->type & 0xff, - rsrc->type, + (unsigned long) rsrc->type, rsrc->id, - rsrc->offset); + (unsigned long) rsrc->offset); } /* Append the new resource to the list */ @@ -1498,10 +1505,10 @@ pdb_LoadRecIndex(int fd, "\tRecord %d: offset 0x%08lx, flags 0x%02x, " " category 0x%02x, ID 0x%08lx\n", i, - rec->offset, - rec->flags, + (unsigned long) rec->offset, + (unsigned) rec->flags, rec->category, - rec->id); + (unsigned long) rec->id); /* Append the new record to the database */ pdb_AppendRecord(db, rec); /* XXX - Error-checking */ @@ -1523,7 +1530,7 @@ pdb_LoadAppBlock(int fd, int err; udword next_off; /* Offset of the next thing in the file * after the AppInfo block */ - udword offset; /* Offset into file, for checking */ + off_t offset; /* Offset into file, for checking */ /* Check to see if there even *is* an AppInfo block */ if (db->appinfo_offset == 0L) @@ -1584,10 +1591,10 @@ pdb_LoadAppBlock(int fd, * we've already passed the beginning of the AppInfo block, as * given by its offset in the header. */ - offset = (udword) lseek(fd, 0L, SEEK_CUR); /* Find out where we are */ + offset = lseek(fd, 0L, SEEK_CUR); /* Find out where we are */ if (offset != db->appinfo_offset) { - if (offset > db->appinfo_offset) + if (offset > (off_t) db->appinfo_offset) { /* Oops! We're in the wrong place */ fprintf(stderr, _("Warning: AppInfo block in \"%.*s\" " @@ -1596,7 +1603,7 @@ pdb_LoadAppBlock(int fd, "Expected 0x%lx, but we're at " "0x%lx.\n"), PDB_DBNAMELEN, db->name, - db->appinfo_offset, (long) offset); + (unsigned long) db->appinfo_offset, (unsigned long) offset); } /* Try to recover */ @@ -1640,7 +1647,7 @@ pdb_LoadSortBlock(int fd, int err; localID next_off; /* Offset of the next thing in the file * after the sort block */ - localID offset; /* Offset into file, for checking */ + off_t offset; /* Offset into file, for checking */ /* Check to see if there even *is* a sort block */ if (db->sortinfo_offset == 0L) @@ -1697,10 +1704,10 @@ pdb_LoadSortBlock(int fd, * we've already passed the beginning of the sort block, as given * by its offset in the header. */ - offset = (udword) lseek(fd, 0L, SEEK_CUR); /* Find out where we are */ + offset = lseek(fd, 0L, SEEK_CUR); /* Find out where we are */ if (offset != db->sortinfo_offset) { - if (offset > db->sortinfo_offset) + if (offset > (off_t) db->sortinfo_offset) { /* Oops! We're in the wrong place */ fprintf(stderr, _("Warning: sort block in \"%.*s\" " @@ -1709,7 +1716,8 @@ pdb_LoadSortBlock(int fd, "Expected 0x%lx, but we're at " "0x%lx.\n"), PDB_DBNAMELEN, db->name, - db->sortinfo_offset, (long) offset); + (unsigned long) db->sortinfo_offset, + (unsigned long) offset); } /* Try to recover */ @@ -1757,7 +1765,7 @@ pdb_LoadResources(int fd, i < db->numrecs; i++, rsrc = rsrc->next) { - udword offset; /* Current offset, for checking */ + off_t offset; /* Current offset, for checking */ udword next_off; /* Offset of next resource in file */ /* Sanity check: make sure we haven't stepped off the end @@ -1787,11 +1795,11 @@ pdb_LoadResources(int fd, * whether we've already passed the beginning of the * resource, as given by its offset in the resource index. */ - offset = (udword) lseek(fd, 0L, SEEK_CUR); + offset = lseek(fd, 0L, SEEK_CUR); /* Find out where we are now */ if (offset != rsrc->offset) { - if (offset > rsrc->offset) + if (offset > (off_t) rsrc->offset) { fprintf(stderr, _("Warning: resource %d in " "\"%.*s\" isn't where " @@ -1800,7 +1808,8 @@ pdb_LoadResources(int fd, "at 0x%lx.\n"), i, PDB_DBNAMELEN, db->name, - rsrc->offset, (long) offset); + (unsigned long) rsrc->offset, + (unsigned long) offset); } /* Try to recover */ @@ -1895,7 +1904,7 @@ pdb_LoadRecords(int fd, i < db->numrecs; i++, rec = rec->next) { - udword offset; /* Current offset, for checking */ + off_t offset; /* Current offset, for checking */ localID next_off; /* Offset of next resource in file */ /* Sanity check: make sure we haven't stepped off the end @@ -1912,7 +1921,7 @@ pdb_LoadRecords(int fd, PDB_TRACE(5) fprintf(stderr, "Reading record %d (id 0x%08lx)\n", - i, rec->id); + i, (unsigned long) rec->id); /* Out of paranoia, make sure we're in the right place. * Since the two NULs may or may not have appeared in the @@ -1920,11 +1929,11 @@ pdb_LoadRecords(int fd, * whether we've already passed the beginning of the * record, as given by its offset in the record index. */ - offset = (udword) lseek(fd, 0L, SEEK_CUR); + offset = lseek(fd, 0L, SEEK_CUR); /* Find out where we are now */ if (offset != rec->offset) { - if (offset > rec->offset) + if (offset > (off_t) rec->offset) { fprintf(stderr, _("Warning: record %d in " "\"%.*s\" isn't where " @@ -1933,7 +1942,8 @@ pdb_LoadRecords(int fd, "at 0x%lx.\n"), i, PDB_DBNAMELEN, db->name, - rec->offset, (long) offset); + (unsigned long) rec->offset, + (unsigned long) offset); } /* Try to recover */ @@ -2025,3 +2035,4 @@ pdb_LoadRecords(int fd, * fill-column: 75 *** * End: *** */ +#endif /* PDBFMTS_DISABLED */ diff --git a/coldsync/util.c b/coldsync/util.c index 61be647fb..3afb545d7 100644 --- a/coldsync/util.c +++ b/coldsync/util.c @@ -12,10 +12,12 @@ * native format, convert them to Palm (big-endian) format, and write * them to a ubyte string. * - * $Id: util.c,v 1.4 2005/03/18 03:56:35 robertl Exp $ + * $Id: util.c,v 1.6 2006/05/07 02:14:35 robertl Exp $ */ #include "config.h" +#include "cs-config.h" +#if PDBFMTS_ENABLED #include #include /* For isprint() */ #include @@ -288,3 +290,4 @@ debug_dump(FILE *outfile, const char *prefix, * fill-column: 75 *** * End: *** */ +#endif diff --git a/compegps.c b/compegps.c new file mode 100644 index 000000000..3156c55bd --- /dev/null +++ b/compegps.c @@ -0,0 +1,663 @@ +/* + + Support for CompeGPS waypoint (.wpt), route (.rte) and track (.trk) files, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + History: + 10/23/2005: First release; only a reader + 10/25/2005: becomes a writer too + 10/26/2005: received documention from CompeGPS team + added fatals for "G" and "U" if not WGS84 and lat/lon + 08/13/2006: switch to gbfile api +*/ + +/* + + the meaning of leading characters in CompeGPS data lines (enhanced PCX): + + header lines: + + "G": WGS 84 - Datum of the map + "N": Anybody - Name of the user + "L": -02:00:00 - Difference to UTC + "M": ... - Any comments + "R": 16711680 , xxxx , 1 - Route header + "U": 1 - System of coordinates (0=UTM 1=Latitude/Longitude) + + "C": 0 0 255 2 -1.000000 - ??? + "V": 0.0 0.0 0 0 0 0 0.0 - ??? + "E": 0|1|00-NUL-00 00:00:00|00:00:00|0 - ??? + + data lines: + + "W": if(route) routepoint; else waypoint + "T": trackpoint + "t": if(track) additionally track info + if(!track) additionally trackpoint info + "a": link to ... + "w": waypoint additional info + +*/ + +#include "defs.h" +#include "csv_util.h" + +#if CSVFMTS_ENABLED +#include +#include +#include +#include +#include +#include "jeeps/gpsmath.h" + +#define MYNAME "CompeGPS" + +#define SHORT_NAME_LENGTH 16 + +static gbfile *fin, *fout; +static int target_index, curr_index; +static int track_info_flag; +static short_handle sh; +static int snlen; +static int radius; +static int input_datum; + +static route_head *curr_track; +static route_head *curr_route; + +/* placeholders for options */ + +static char *option_icon; +static char *option_index; +static char *option_radius; +static char *option_snlen; + +static +arglist_t compegps_args[] = { + {"deficon", &option_icon, "Default icon name", + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"index", &option_index, "Index of route/track to write (if more the one in source)", + NULL, ARGTYPE_INT, "1", NULL}, + {"radius", &option_radius, "Give points (waypoints/route points) a default radius (proximity)", + NULL, ARGTYPE_FLOAT, "0", NULL}, + {"snlen", &option_snlen, "Length of generated shortnames (default 16)", + "16", ARGTYPE_INT, "1", NULL}, + ARG_TERMINATOR +}; + +static +void fix_datum(double *lat, double *lon) +{ + double amt; + static int wgs84; + + if (wgs84 == 0) { + wgs84 = GPS_Lookup_Datum_Index("WGS 84"); + } + + /* + * Avoid FP jitter in the common case. + */ + if (input_datum != wgs84) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, lat, lon, + &amt, input_datum); + } +} + +/* specialized readers */ + +static waypoint* +parse_wpt(char *buff) +{ + int col = -1; + char *c, *cx; + waypoint *wpt = waypt_new(); + + c = strstr(buff, "A "); + if (c == buff) col++; + + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_wpt: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: + + cx = c + strlen(c) - 1; /* trim trailing underscores */ + while ((cx >= c) && (*cx == '_')) *cx-- = '\0'; + if (*c != '\0') + wpt->shortname = xstrdup(c); + break; + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + case 4: break; /* Unused date and time */ + case 5: break; /* always "27-MAR-62 00:00:00" */ + case 6: + wpt->altitude = atof(c); + break; + case 7: + wpt->description = xstrdup(c); + break; + default: + if (col > 7) + { + wpt->description = xstrappend(wpt->description, " "); + wpt->description = xstrappend(wpt->description, c); + } + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; +} + +static void +parse_wpt_info(const char *buff, waypoint *wpt) /* "w" */ +{ + char *c; + int col = -1; + double fx; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_wpt_info: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: + wpt->icon_descr = xstrdup(c); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 1: break; /* Text postion */ + case 2: break; /* Lens zoom level */ + case 3: break; /* Text colour */ + case 4: break; /* Background colour */ + case 5: break; /* Transparent text  (0=transparent, 1=no transparent) */ + case 6: break; /* ??? */ + case 7: break; /* ??? */ + case 8: /* radius */ + fx = atof(c); + if (fx > 0) + wpt->proximity = fx; + break; + } + } + c = csv_lineparse(NULL, ",", "", col++); + } +} + +static waypoint * +parse_trkpt(char *buff) +{ + int col = -1; + char *c; + struct tm tm; + char month[4]; + waypoint *wpt = waypt_new(); + + c = strstr(buff, "A "); + if (c == buff) col++; + + memset(&tm, 0, sizeof(tm)); + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_trkpt: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + case 4: + tm.tm_mday = atoi(c); + strncpy(month, c+3, 3); + month[3] = 0; + tm.tm_mon = month_lookup(month); + tm.tm_year = atoi(c + 7); + if (tm.tm_year < 70) tm.tm_year += 100; + break; + case 5: + tm.tm_hour = atoi(c); + tm.tm_min = atoi(c+3); + tm.tm_sec = atoi(c+6); + wpt->creation_time = mkgmtime(&tm); + break; + case 7: + wpt->altitude = atof(c); + break; + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; +} + +static void +parse_track_info(const char *buff, route_head *track) /* "t" */ +{ + char *c; + int col = -1; + + c = csv_lineparse(buff, "|", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_track_info: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: + break; /* unknown field */ + case 1: + track->rte_name = xstrdup(c); + break; + case 2: + break; /* unknown field */ + case 3: + break; /* unknown field */ + } + } + c = csv_lineparse(NULL, "|", "", col++); + } +} + +static void +parse_rte_info(const char *buff, route_head *route) /* "R" */ +{ + char *c; + int col = -1; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) + { + c = lrtrim(c); + if (*c != '\0') + { +#if 0 + printf(MYNAME "_read_rte_info: col(%d)=%s\n", col, c); +#endif + switch(col) + { + case 0: break; /* unknown field (colour?) */ + case 1: + route->rte_name = xstrdup(c); + break; + case 2: break; /* unknown field */ + + } + } + c = csv_lineparse(NULL, ",", "", col++); + } +} + +/* main functions */ + +static void +compegps_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + input_datum = GPS_Lookup_Datum_Index("WGS 84"); +} + +static void +compegps_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +compegps_data_read(void) +{ + char *buff; + int line = 0; + int input_datum; + waypoint *wpt = NULL; + route_head *route = NULL; + route_head *track = NULL; + + while ((buff = gbfgetstr(fin))) + { + char *cin = buff; + char *ctail; + + line++; + cin = lrtrim(buff); + if (strlen(cin) == 0) continue; + + ctail = strchr(cin, ' '); + if (ctail == NULL) continue; + ctail = lrtrim(ctail); + + switch(*cin) + { + case 'G': + input_datum = GPS_Lookup_Datum_Index(ctail); + if (input_datum < 0) { + fatal( MYNAME ": Unsupported datum \"%s\"!", ctail); + } + break; + case 'U': + switch(*ctail) + { + case '1': /* lat/lon, that's we want to see */ + break; + case '0': /* UTM not supported yet */ + fatal(MYNAME "Sorry, UTM is not supported yet!\n"); + default: + fatal(MYNAME "Invalid system of coordinates (%s)!\n", cin); + } + break; + case 'R': + route = route_head_alloc(); + route_add_head(route); + parse_rte_info(ctail, route); + break; + case 'M': + break; + case 'W': + wpt = parse_wpt(ctail); + if (wpt != NULL) + { + if (route != NULL) + route_add_wpt(route, wpt); + else + waypt_add(wpt); + } + break; + case 'w': + is_fatal((wpt == NULL), MYNAME ": No waypoint data before \"%s\"!", cin); + parse_wpt_info(ctail, wpt); + break; + case 'T': + wpt = parse_trkpt(ctail); + if (wpt != NULL) + { + if (track == NULL) + { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + } + break; + case 't': + if (track != NULL) + parse_track_info(ctail, track); + break; + } + } +} + +/* ----------------------------------------------------------- */ + +static void +write_waypt_cb(const waypoint *wpt) +{ + char *name; + + if (curr_index != target_index ) return; + + name = (snlen > 0) ? mkshort_from_wpt(sh, wpt) : csv_stringclean(wpt->shortname, " "); + + gbfprintf(fout, "W %s A ", name); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S'); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "27-MAR-62 00:00:00 %.6f", + (wpt->altitude != unknown_alt) ? wpt->altitude : 0.0); + if (wpt->description != NULL) + gbfprintf(fout, " %s", wpt->description); + gbfprintf(fout, "\n"); + + if ((wpt->icon_descr != NULL) || (wpt->proximity > 0.0) || \ + (option_icon != NULL)) + { + char *icon = option_icon; + + if (wpt->icon_descr != NULL) icon = (char *) wpt->icon_descr; + + gbfprintf(fout, "w %s,0,0.0,16777215,255,1,7,,%.1f\n", + (icon != NULL) ? icon : "Waypoint", + (wpt->proximity > 0.0f) ? wpt->proximity : 0.0); + } + xfree(name); +} + +static void +write_route_hdr_cb(const route_head *rte) +{ + char *name; + curr_route = (route_head *) rte; + curr_index++; + if (curr_index != target_index) return; + + name = rte->rte_name; + if (name != NULL) + name = csv_stringclean(name, ","); + else + name = xstrdup(" "); + gbfprintf(fout, "R 16711680,%s,1,-1\n", name); + xfree(name); +} + +static void +write_route(void) +{ + curr_index = 0; + route_disp_all(write_route_hdr_cb, NULL, write_waypt_cb); +} + +static void +write_track_hdr_cb(const route_head *trk) +{ + track_info_flag = 0; + curr_track = (route_head *) trk; + + curr_index++; + if (curr_index != target_index) return; + + track_info_flag = 1; +} + +static void +write_trkpt_cb(const waypoint *wpt) +{ + char buff[128]; + struct tm tm; + + if ((curr_index != target_index) || (wpt == NULL)) return; + + buff[0] = '\0'; + + if (wpt->creation_time != 0) + { + tm = *gmtime(&wpt->creation_time); + strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); + strupper(buff); + } + + gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", + buff, + wpt->altitude, + 0.0, + 0.0, + 0.0, + 0); + gbfprintf(fout, "%.1f %.1f %.1f %.1f %.1f\n", + -1000.0, + -1.0, + -1.0, + -1.0, + -1.0); + if (track_info_flag != 0) + { + track_info_flag = 0; + if (curr_track->rte_name != NULL) + { + char *name; + + name = csv_stringclean(curr_track->rte_name, "|"); + gbfprintf(fout, "t 4294967295|%s|-1|-1\n", name); + xfree(name); + } + } +} + +static void +write_track(void) +{ + curr_index = 0; + +// gbfprintf(fout, "L +02:00:00\n"); + track_disp_all(write_track_hdr_cb, NULL, write_trkpt_cb); + gbfprintf(fout, "F 1234\n"); +} + +static void +write_waypoints(void) +{ + waypt_disp_all(write_waypt_cb); +} + +/* --------------------------------------------------------------------------- */ + +static void +compegps_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); + sh = mkshort_new_handle(); +} + +static void +compegps_wr_deinit(void) +{ + mkshort_del_handle(&sh); + gbfclose(fout); +} + +static void +compegps_data_write(void) +{ + /* because of different file extensions we can only write one GPS data type at time */ + + gbfprintf(fout, "G WGS 84\n"); + gbfprintf(fout, "U 1\n"); + + /* process options */ + + target_index = 1; + if (option_index != NULL) + target_index = atoi(option_index); + + snlen = 0; + if (global_opts.synthesize_shortnames != 0) + { + if (option_snlen != NULL) + snlen = atoi(option_snlen); + else + snlen = SHORT_NAME_LENGTH; + + is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!"); + + setshort_whitespace_ok(sh, 0); + setshort_length(sh, snlen); + } + + radius = -1; + if (option_radius != 0) + { + radius = atof(option_radius); + is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!"); + } + + if (option_icon != NULL) + { + if (*option_icon == '\0') + option_icon = NULL; + else if (case_ignore_strcmp(option_icon, "deficon") == 0) + option_icon = NULL; + } + + switch(global_opts.objective) + { + case wptdata: + curr_index = target_index = 0; + write_waypoints(); + break; + case trkdata: + write_track(); + break; + case rtedata: + write_route(); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t compegps_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + compegps_rd_init, + compegps_wr_init, + compegps_rd_deinit, + compegps_wr_deinit, + compegps_data_read, + compegps_data_write, + NULL, + compegps_args, + CET_CHARSET_MS_ANSI, 1 +}; +#endif /* CSVFMTS_ENABLED */ diff --git a/config.guess b/config.guess new file mode 100644 index 000000000..917bbc50f --- /dev/null +++ b/config.guess @@ -0,0 +1,1463 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..0e668d4f0 --- /dev/null +++ b/config.h.in @@ -0,0 +1,59 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* 0 for most-used character sets */ +#undef CET_WANTED + +/* 1 to enable the CSV formats support */ +#undef CSVFMTS_ENABLED + +/* 1 to enable all the filters. */ +#undef FILTERS_ENABLED + +/* Defined if you have libexpat */ +#undef HAVE_LIBEXPAT + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Defined if you have libusb */ +#undef HAVE_LIBUSB + +/* Define to 1 if you have the `z' library (-lz). */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the `nanosleep' function. */ +#undef HAVE_NANOSLEEP + +/* Define to 1 if you have the `sleep' function. */ +#undef HAVE_SLEEP + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the release name of this package. */ +#undef PACKAGE_RELEASE + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* 1 to enable Palm PDB support */ +#undef PDBFMTS_ENABLED + +/* 1 to enable shapefile support */ +#undef SHAPELIB_ENABLED + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* 1 to inhibit our use of zlib. */ +#undef ZLIB_INHIBITED diff --git a/config.sub b/config.sub new file mode 100644 index 000000000..1c366dfde --- /dev/null +++ b/config.sub @@ -0,0 +1,1579 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100644 index 000000000..9b7086aaa --- /dev/null +++ b/configure @@ -0,0 +1,4603 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59 for GPSBabel 1.3.2. +# +# Report bugs to . +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='GPSBabel' +PACKAGE_TARNAME='gpsbabel' +PACKAGE_VERSION='1.3.2' +PACKAGE_STRING='GPSBabel 1.3.2' +PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS' + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE_RELEASE GBMAJOR GBMINOR GBMICRO build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE FILEINFO RC LIBUSBCONFIG USB_LIBS USB_CFLAGS OSJEEPS GBSER ZLIB EXPAT_LIB EFENCE_LIB GPSBABEL_DEBUG INSTALL_DEBUG DOCDIR LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GPSBabel 1.3.2 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GPSBabel 1.3.2:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shapefile=(yes)|no + --enable-pdb=(yes)|no + --enable-csv=(yes)|no + --enable-filters=(yes)|no + --enable-efence=yes|(no) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-cet=(default,all,minimal) + --with-zlib=(included)|system|no + --with-expathdr=DIR Use this to specify the location of expat.h + --with-libexpat=DIR Use this to specify expat library . + --with-doc=DIR Path where the documentation will be stored. + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +GPSBabel configure 1.3.2 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GPSBabel $as_me 1.3.2, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# YYYYMMDD, please, if beta, i.e. "-beta20060413" +PACKAGE_RELEASE="" + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_RELEASE "$PACKAGE_RELEASE" +_ACEOF + + + +GBMAJOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $major)` +GBMINOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $minor)` +GBMICRO=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $micro)` + + + + +# AC_CONFIG_SRCDIR([nmea.c]) + ac_config_headers="$ac_config_headers config.h" + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6 +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_target_alias=$target_alias +test "x$ac_cv_target_alias" = "x" && + ac_cv_target_alias=$ac_cv_host_alias +ac_cv_target=`$ac_config_sub $ac_cv_target_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6 +target=$ac_cv_target +target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + + + +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int +main () +{ + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + + +# Checks for libraries. + +echo "$as_me:$LINENO: checking for cos in -lm" >&5 +echo $ECHO_N "checking for cos in -lm... $ECHO_C" >&6 +if test "${ac_cv_lib_m_cos+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char cos (); +int +main () +{ +cos (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_m_cos=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_m_cos=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_m_cos" >&5 +echo "${ECHO_T}$ac_cv_lib_m_cos" >&6 +if test $ac_cv_lib_m_cos = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + + +# Check whether --with-cet or --without-cet was given. +if test "${with_cet+set}" = set; then + withval="$with_cet" + cet="$withval" +else + cet="default" +fi; + +if test $GCC = yes; then + CFLAGS="$CFLAGS -Wall" +fi + +if test "$cet" = "all"; then + +cat >>confdefs.h <<\_ACEOF +#define CET_WANTED 1 +_ACEOF + +fi +if test "$cet" = "default"; then + +cat >>confdefs.h <<\_ACEOF +#define CET_WANTED 0 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether to support shapefiles" >&5 +echo $ECHO_N "checking whether to support shapefiles... $ECHO_C" >&6 +# Check whether --enable-shapefile or --disable-shapefile was given. +if test "${enable_shapefile+set}" = set; then + enableval="$enable_shapefile" + enable_shapefile="$enableval" +else + enable_shapefile="yes" +fi; + if test "$enable_shapefile" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define SHAPELIB_ENABLED 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +echo "$as_me:$LINENO: checking whether to support Palm/OS pdb formats" >&5 +echo $ECHO_N "checking whether to support Palm/OS pdb formats... $ECHO_C" >&6 +# Check whether --enable-pdb or --disable-pdb was given. +if test "${enable_pdb+set}" = set; then + enableval="$enable_pdb" + enable_pdb="$enableval" +else + enable_pdb="yes" +fi; + if test "$enable_pdb" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define PDBFMTS_ENABLED 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +echo "$as_me:$LINENO: checking whether to support csv formats" >&5 +echo $ECHO_N "checking whether to support csv formats... $ECHO_C" >&6 +# Check whether --enable-csv or --disable-csv was given. +if test "${enable_csv+set}" = set; then + enableval="$enable_csv" + enable_csv="$enableval" +else + enable_csv="yes" +fi; + if test "$enable_csv" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define CSVFMTS_ENABLED 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +echo "$as_me:$LINENO: checking whether to support filters" >&5 +echo $ECHO_N "checking whether to support filters... $ECHO_C" >&6 +# Check whether --enable-filters or --disable-filters was given. +if test "${enable_filters+set}" = set; then + enableval="$enable_filters" + enable_filters="$enableval" +else + enable_filters="yes" +fi; + if test "$enable_filters" != "no" ; then + +cat >>confdefs.h <<\_ACEOF +#define FILTERS_ENABLED 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + +echo "$as_me:$LINENO: checking whether to support zlib" >&5 +echo $ECHO_N "checking whether to support zlib... $ECHO_C" >&6 + +# Check whether --with-zlib or --without-zlib was given. +if test "${with_zlib+set}" = set; then + withval="$with_zlib" + +fi; + case $with_zlib in + "system") + +echo "$as_me:$LINENO: checking for gzopen in -lz" >&5 +echo $ECHO_N "checking for gzopen in -lz... $ECHO_C" >&6 +if test "${ac_cv_lib_z_gzopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gzopen (); +int +main () +{ +gzopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_z_gzopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_z_gzopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzopen" >&5 +echo "${ECHO_T}$ac_cv_lib_z_gzopen" >&6 +if test $ac_cv_lib_z_gzopen = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBZ 1 +_ACEOF + + LIBS="-lz $LIBS" + +fi + + ;; + "no") + +cat >>confdefs.h <<\_ACEOF +#define ZLIB_INHIBITED 1 +_ACEOF + + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + ;; + *) ZLIB="\$(ZLIB)" + echo "$as_me:$LINENO: result: using included version" >&5 +echo "${ECHO_T}using included version" >&6;; + esac + +case "$target" in + *-*-mingw32*) + FILEINFO=fileinfo.o + if test "$CC" = gcc ; then + RC=windres + else + RC=`echo "$CC" | sed -e 's/gcc$/windres/'` + fi + ;; + *) + RC=false + ;; +esac + + + +case "$target" in + *-*-cygwin* | *-*-mingw32*) + + GBSER=gbser_win.o + + if test "$with_libusb" = no ; then + echo "$as_me:$LINENO: result: USB skipped" >&5 +echo "${ECHO_T}USB skipped" >&6 + OSJEEPS=jeeps/gpsusbstub.o + else + OSJEEPS=jeeps/gpsusbwin.o + USB_LIBS=-lsetupapi + fi + ;; + *) + GBSER=gbser_posix.o + echo "$as_me:$LINENO: checking for libusb" >&5 +echo $ECHO_N "checking for libusb... $ECHO_C" >&6 + if test "$with_libusb" = no ; then + echo "$as_me:$LINENO: result: check not done" >&5 +echo "${ECHO_T}check not done" >&6 + OSJEEPS=jeeps/gpsusbstub.o + else + # Extract the first word of "libusb-config", so it can be a program name with args. +set dummy libusb-config; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_LIBUSBCONFIG+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$LIBUSBCONFIG"; then + ac_cv_prog_LIBUSBCONFIG="$LIBUSBCONFIG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIBUSBCONFIG="true" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_LIBUSBCONFIG" && ac_cv_prog_LIBUSBCONFIG="false" +fi +fi +LIBUSBCONFIG=$ac_cv_prog_LIBUSBCONFIG +if test -n "$LIBUSBCONFIG"; then + echo "$as_me:$LINENO: result: $LIBUSBCONFIG" >&5 +echo "${ECHO_T}$LIBUSBCONFIG" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + if test "$LIBUSBCONFIG" = true; then + OLDFLAGS=$LDFLAGS + OCFLAGS=$CFLAGS + LDFLAGS="$LDFLAGS `libusb-config --libs`" + CFLAGS="$OCFLAGS `libusb-config --cflags`" + + echo "$as_me:$LINENO: checking for usb_interrupt_read in -lusb" >&5 +echo $ECHO_N "checking for usb_interrupt_read in -lusb... $ECHO_C" >&6 +if test "${ac_cv_lib_usb_usb_interrupt_read+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lusb $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char usb_interrupt_read (); +int +main () +{ +usb_interrupt_read (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_usb_usb_interrupt_read=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_usb_usb_interrupt_read=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_interrupt_read" >&5 +echo "${ECHO_T}$ac_cv_lib_usb_usb_interrupt_read" >&6 +if test $ac_cv_lib_usb_usb_interrupt_read = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBUSB 1 +_ACEOF + + USB_CFLAGS="`libusb-config --cflags`" + USB_LIBS="`libusb-config --libs`" +# ,[AC_MSG_ERROR([libusb >= 0.1.8 is needed])] + +fi + + # Override libusb for Darwin to reduce external + # runtime requirement. + case "$target" in + *-*-darwin*) + if test "x$ac_cv_lib_usb_usb_interrupt_read" = "xyes" ; then + USB_LIBS="`libusb-config --prefix`/lib/libusb.a -framework IOKit -framework CoreFoundation" + LDFLAGS=$OLDFLAGS + CDFLAGS=$OCDFLAGS + fi + esac + OSJEEPS=jeeps/gpslibusb.o + CFLAGS="$OCFLAGS" + # LIBS="$LIBS `libusb-config --libs`" + else + OSJEEPS=jeeps/gpsusbstub.o + fi + fi + ;; +esac + + + + + + + +echo "$as_me:$LINENO: checking for random stuff to make you feel better" >&5 +echo $ECHO_N "checking for random stuff to make you feel better... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 + + +# Check whether --with-expathdr or --without-expathdr was given. +if test "${with_expathdr+set}" = set; then + withval="$with_expathdr" + xpathdr="$withval" +else + + case "$target" in + *-*-darwin*) + if test -f /sw/include/expat.h ; then + xpathdr=/sw/include/ + fi + ;; + *) ;; + esac + + +fi; + +if test "x-$xpathdr" != "x-" ; then + CFLAGS="$CFLAGS -I$xpathdr" +fi + +echo "$as_me:$LINENO: checking for libexpat" >&5 +echo $ECHO_N "checking for libexpat... $ECHO_C" >&6 + +# Check whether --with-libexpat or --without-libexpat was given. +if test "${with_libexpat+set}" = set; then + withval="$with_libexpat" + CFLAGS="$CFLAGS -L$withval" + EXPAT_LIB="-L$withval -lexpat" + +else + + case "$target" in + *-*-darwin*) + if test -f /sw/lib/libexpat.a ; then + EXPAT_LIB=/sw/lib/libexpat.a + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + fi + ;; + *) + EXPAT_LIB=-lexpat + ;; + esac + + +fi; +echo "$as_me:$LINENO: result: $EXPAT_LIB" >&5 +echo "${ECHO_T}$EXPAT_LIB" >&6 + +echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5 +echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6 +if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lexpat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XML_ParserCreate (); +int +main () +{ +XML_ParserCreate (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_expat_XML_ParserCreate=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_expat_XML_ParserCreate=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 +echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6 +if test $ac_cv_lib_expat_XML_ParserCreate = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBEXPAT 1 +_ACEOF + + + +fi + + +echo "$as_me:$LINENO: checking for efence" >&5 +echo $ECHO_N "checking for efence... $ECHO_C" >&6 +# Check whether --enable-efence or --disable-efence was given. +if test "${enable_efence+set}" = set; then + enableval="$enable_efence" + if test "$enable_efence" != "no" ; then + EFENCE_LIB=-lefence + GPSBABEL_DEBUG=gpsbabel-debug + INSTALL_DEBUG=install-debug + fi +fi; + + + +echo "$as_me:$LINENO: result: $EFENCE_LIB" >&5 +echo "${ECHO_T}$EFENCE_LIB" >&6 + +echo "$as_me:$LINENO: checking for docdir" >&5 +echo $ECHO_N "checking for docdir... $ECHO_C" >&6 + +# Check whether --with-doc or --without-doc was given. +if test "${with_doc+set}" = set; then + withval="$with_doc" + DOCDIR="$withval" +else + DOCDIR="../babelweb/" +fi; + + +# Checks for header files. +# AC_HEADER_STDC + +# AC_CHECK_HEADERS([fcntl.h inttypes.h libintl.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/time.h termios.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +# AC_C_CONST +# AC_C_INLINE +# AC_TYPE_OFF_T +# AC_TYPE_SIZE_T +# AC_HEADER_TIME +# AC_STRUCT_TM +# AC_STRUCT_TIMEZONE + +# Checks for library functions. +# AC_FUNC_MALLOC +# AC_FUNC_MEMCMP +# AC_FUNC_MKTIME +# AC_FUNC_REALLOC +# AC_FUNC_SELECT_ARGTYPES +# AC_FUNC_STRFTIME +# AC_FUNC_STRTOD +# AC_FUNC_VPRINTF +# AC_CHECK_FUNCS([atexit floor localtime_r memmove memset pow select sqrt strchr strcspn strdup strerror strncasecmp strrchr strspn strstr strtol strtoul]) + + +for ac_func in nanosleep sleep +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + ac_config_files="$ac_config_files Makefile xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc coldsync/Makefile jeeps/Makefile shapelib/Makefile zlib/empty" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by GPSBabel $as_me 1.3.2, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +GPSBabel config.status 1.3.2 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "xmldoc/makedoc" ) CONFIG_FILES="$CONFIG_FILES xmldoc/makedoc" ;; + "tools/mkcapabilities" ) CONFIG_FILES="$CONFIG_FILES tools/mkcapabilities" ;; + "win32/gpsbabel.rc" ) CONFIG_FILES="$CONFIG_FILES win32/gpsbabel.rc" ;; + "coldsync/Makefile" ) CONFIG_FILES="$CONFIG_FILES coldsync/Makefile" ;; + "jeeps/Makefile" ) CONFIG_FILES="$CONFIG_FILES jeeps/Makefile" ;; + "shapelib/Makefile" ) CONFIG_FILES="$CONFIG_FILES shapelib/Makefile" ;; + "zlib/empty" ) CONFIG_FILES="$CONFIG_FILES zlib/empty" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@PACKAGE_RELEASE@,$PACKAGE_RELEASE,;t t +s,@GBMAJOR@,$GBMAJOR,;t t +s,@GBMINOR@,$GBMINOR,;t t +s,@GBMICRO@,$GBMICRO,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@target@,$target,;t t +s,@target_cpu@,$target_cpu,;t t +s,@target_vendor@,$target_vendor,;t t +s,@target_os@,$target_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@FILEINFO@,$FILEINFO,;t t +s,@RC@,$RC,;t t +s,@LIBUSBCONFIG@,$LIBUSBCONFIG,;t t +s,@USB_LIBS@,$USB_LIBS,;t t +s,@USB_CFLAGS@,$USB_CFLAGS,;t t +s,@OSJEEPS@,$OSJEEPS,;t t +s,@GBSER@,$GBSER,;t t +s,@ZLIB@,$ZLIB,;t t +s,@EXPAT_LIB@,$EXPAT_LIB,;t t +s,@EFENCE_LIB@,$EFENCE_LIB,;t t +s,@GPSBABEL_DEBUG@,$GPSBABEL_DEBUG,;t t +s,@INSTALL_DEBUG@,$INSTALL_DEBUG,;t t +s,@DOCDIR@,$DOCDIR,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..55b9aa081 --- /dev/null +++ b/configure.in @@ -0,0 +1,278 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) + +AC_INIT(GPSBabel, 1.3.2, BUG-REPORT-ADDRESS) + +# YYYYMMDD, please, if beta, i.e. "-beta20060413" +PACKAGE_RELEASE="" +AC_DEFINE_UNQUOTED(PACKAGE_RELEASE, "$PACKAGE_RELEASE", [Define to the release name of this package.]) +AC_SUBST(PACKAGE_RELEASE) + +GBMAJOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $major)` +GBMINOR=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $minor)` +GBMICRO=`echo $PACKAGE_VERSION | (IFS="."; read major minor micro; echo $micro)` +AC_SUBST(GBMAJOR) +AC_SUBST(GBMINOR) +AC_SUBST(GBMICRO) + +# AC_CONFIG_SRCDIR([nmea.c]) +AC_CONFIG_HEADER([config.h]) + +dnl Detect the canonical host and target build environment +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +# Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_MAKE_SET +AC_EXEEXT +AC_SUBST(AC_EXEEXT) +AC_C_BIGENDIAN + +# Checks for libraries. +AC_CHECK_LIB([m], [cos]) + +AC_ARG_WITH(cet,[ --with-cet=(default,all,minimal)], + cet="$withval", cet="default") + +if test $GCC = yes; then + CFLAGS="$CFLAGS -Wall" +fi + +if test "$cet" = "all"; then + AC_DEFINE(CET_WANTED, 1, [1 for all character sets]) +fi +if test "$cet" = "default"; then + AC_DEFINE(CET_WANTED, 0, [0 for most-used character sets]) +fi + +AC_MSG_CHECKING(whether to support shapefiles) +AC_ARG_ENABLE(shapefile, + [ --enable-shapefile=[(yes)|no]], + [ enable_shapefile="$enableval"],[enable_shapefile="yes"]) + if test "$enable_shapefile" != "no" ; then + AC_DEFINE(SHAPELIB_ENABLED, 1, [1 to enable shapefile support]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support Palm/OS pdb formats) +AC_ARG_ENABLE(pdb, + [ --enable-pdb=[(yes)|no]], + [ enable_pdb="$enableval"],[enable_pdb="yes"]) + if test "$enable_pdb" != "no" ; then + AC_DEFINE(PDBFMTS_ENABLED, 1, [1 to enable Palm PDB support]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support csv formats) +AC_ARG_ENABLE(csv, + [ --enable-csv=[(yes)|no]], + [ enable_csv="$enableval"],[enable_csv="yes"]) + if test "$enable_csv" != "no" ; then + AC_DEFINE(CSVFMTS_ENABLED, 1, [1 to enable the CSV formats support]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support filters) +AC_ARG_ENABLE(filters, + [ --enable-filters=[(yes)|no]], + [ enable_filters="$enableval"],[enable_filters="yes"]) + if test "$enable_filters" != "no" ; then + AC_DEFINE(FILTERS_ENABLED, 1, [1 to enable all the filters.]) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + +AC_MSG_CHECKING(whether to support zlib) +AC_ARG_WITH(zlib, [ --with-zlib=[(included)|system|no]]) + case $with_zlib in + "system") + AC_CHECK_LIB([z], [gzopen]) + ;; + "no") + AC_DEFINE(ZLIB_INHIBITED, 1, [1 to inhibit our use of zlib.]) + AC_MSG_RESULT(no) + ;; + *) ZLIB="\$(ZLIB)" + AC_MSG_RESULT(using included version);; + esac + +case "$target" in + *-*-mingw32*) + FILEINFO=fileinfo.o + if test "$CC" = gcc ; then + RC=windres + else + RC=`echo "$CC" | sed -e 's/gcc$/windres/'` + fi + ;; + *) + RC=false + ;; +esac +AC_SUBST(FILEINFO) +AC_SUBST(RC) + +case "$target" in + *-*-cygwin* | *-*-mingw32*) + + GBSER=gbser_win.o + + if test "$with_libusb" = no ; then + AC_MSG_RESULT(USB skipped) + OSJEEPS=jeeps/gpsusbstub.o + else + OSJEEPS=jeeps/gpsusbwin.o + USB_LIBS=-lsetupapi + fi + ;; + *) + GBSER=gbser_posix.o + AC_MSG_CHECKING(for libusb) + if test "$with_libusb" = no ; then + AC_MSG_RESULT(check not done) + OSJEEPS=jeeps/gpsusbstub.o + else + AC_CHECK_PROG(LIBUSBCONFIG, libusb-config, true, false) + if test "$LIBUSBCONFIG" = true; then + OLDFLAGS=$LDFLAGS + OCFLAGS=$CFLAGS + LDFLAGS="$LDFLAGS `libusb-config --libs`" + CFLAGS="$OCFLAGS `libusb-config --cflags`" + + AC_CHECK_LIB([usb], [usb_interrupt_read], + AC_DEFINE(HAVE_LIBUSB, 1, [Defined if you have libusb]) + [USB_CFLAGS="`libusb-config --cflags`"] + [USB_LIBS="`libusb-config --libs`"] +# ,[AC_MSG_ERROR([libusb >= 0.1.8 is needed])] + ) + # Override libusb for Darwin to reduce external + # runtime requirement. + case "$target" in + *-*-darwin*) + if test "x$ac_cv_lib_usb_usb_interrupt_read" = "xyes" ; then + USB_LIBS="`libusb-config --prefix`/lib/libusb.a -framework IOKit -framework CoreFoundation" + LDFLAGS=$OLDFLAGS + CDFLAGS=$OCDFLAGS + fi + esac + OSJEEPS=jeeps/gpslibusb.o + CFLAGS="$OCFLAGS" + # LIBS="$LIBS `libusb-config --libs`" + else + OSJEEPS=jeeps/gpsusbstub.o + fi + fi + ;; +esac + +AC_SUBST(USB_LIBS) +AC_SUBST(USB_CFLAGS) +AC_SUBST(OSJEEPS) +AC_SUBST(GBSER) +AC_SUBST(ZLIB) + +AC_MSG_CHECKING(for random stuff to make you feel better) +AC_MSG_RESULT(failed) + +AC_ARG_WITH(expathdr, + [ --with-expathdr[=DIR] Use this to specify the location of expat.h], + [ xpathdr="$withval" ], [ + case "$target" in + *-*-darwin*) + if test -f /sw/include/expat.h ; then + xpathdr=/sw/include/ + fi + ;; + *) ;; + esac +] +) + +if test "x-$xpathdr" != "x-" ; then + CFLAGS="$CFLAGS -I$xpathdr" +fi + +AC_MSG_CHECKING(for libexpat) +AC_ARG_WITH(libexpat, + [ --with-libexpat[=DIR] Use this to specify expat library .], + [ CFLAGS="$CFLAGS -L$withval" + EXPAT_LIB="-L$withval -lexpat" + ], [ + case "$target" in + *-*-darwin*) + if test -f /sw/lib/libexpat.a ; then + EXPAT_LIB=/sw/lib/libexpat.a + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) + fi + ;; + *) + EXPAT_LIB=-lexpat + ;; + esac + ] +) +AC_MSG_RESULT($EXPAT_LIB) + +AC_CHECK_LIB([expat], [XML_ParserCreate], + AC_DEFINE(HAVE_LIBEXPAT, 1, [Defined if you have libexpat]) + AC_SUBST(EXPAT_LIB) +) + +AC_MSG_CHECKING(for efence) +AC_ARG_ENABLE(efence, + [ --enable-efence=[yes|(no)]], + [ if test "$enable_efence" != "no" ; then + EFENCE_LIB=-lefence + GPSBABEL_DEBUG=gpsbabel-debug + INSTALL_DEBUG=install-debug + fi]) +AC_SUBST(EFENCE_LIB) +AC_SUBST(GPSBABEL_DEBUG) +AC_SUBST(INSTALL_DEBUG) +AC_MSG_RESULT($EFENCE_LIB) + +AC_MSG_CHECKING(for docdir) +AC_ARG_WITH(doc,[ --with-doc=DIR Path where the documentation will be stored.], + DOCDIR="$withval", DOCDIR="../babelweb/") +AC_SUBST(DOCDIR) + +# Checks for header files. +# AC_HEADER_STDC + +# AC_CHECK_HEADERS([fcntl.h inttypes.h libintl.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/time.h termios.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +# AC_C_CONST +# AC_C_INLINE +# AC_TYPE_OFF_T +# AC_TYPE_SIZE_T +# AC_HEADER_TIME +# AC_STRUCT_TM +# AC_STRUCT_TIMEZONE + +# Checks for library functions. +# AC_FUNC_MALLOC +# AC_FUNC_MEMCMP +# AC_FUNC_MKTIME +# AC_FUNC_REALLOC +# AC_FUNC_SELECT_ARGTYPES +# AC_FUNC_STRFTIME +# AC_FUNC_STRTOD +# AC_FUNC_VPRINTF +# AC_CHECK_FUNCS([atexit floor localtime_r memmove memset pow select sqrt strchr strcspn strdup strerror strncasecmp strrchr strspn strstr strtol strtoul]) +AC_CHECK_FUNCS([nanosleep sleep]) + +AC_CONFIG_FILES([Makefile xmldoc/makedoc tools/mkcapabilities win32/gpsbabel.rc coldsync/Makefile jeeps/Makefile shapelib/Makefile zlib/empty]) +AC_OUTPUT diff --git a/copilot.c b/copilot.c index 787e5be43..b1b1c903b 100644 --- a/copilot.c +++ b/copilot.c @@ -20,10 +20,10 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" - -static double conv = 180.0 / M_PI; +#include "grtcirc.h" #define MYNAME "CoPilot Waypoint" #define MYTYPE 0x77617970 /* wayp */ @@ -41,8 +41,8 @@ struct record { static FILE *file_in; static FILE *file_out; static const char *out_fname; -struct pdb *opdb; -struct pdb_record *opdb_rec; +static struct pdb *opdb; +static struct pdb_record *opdb_rec; static void rd_init(const char *fname) @@ -92,9 +92,9 @@ data_read(void) rec = (struct record *) pdb_rec->data; wpt_tmp->longitude = - -pdb_read_double(&rec->longitude) * conv; + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - pdb_read_double(&rec->latitude) * conv; + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = pdb_read_double(&rec->elevation) * .3048; @@ -124,9 +124,8 @@ copilot_writewpt(const waypoint *wpt) rec = xcalloc(sizeof(*rec)+1141,1); - pdb_write_double(&rec->latitude, wpt->latitude / conv); - pdb_write_double(&rec->longitude, - -wpt->longitude / conv); + pdb_write_double(&rec->latitude, RAD(wpt->latitude)); + pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); pdb_write_double(&rec->elevation, wpt->altitude / .3048); pdb_write_double(&rec->magvar, 0); @@ -200,5 +199,8 @@ ff_vecs_t copilot_vecs = { wr_deinit, data_read, data_write, - NULL + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/coto.c b/coto.c index 07c835e31..c5dfc59f4 100644 --- a/coto.c +++ b/coto.c @@ -1,7 +1,7 @@ /* - Read and write Coto files. + Read and write cotoGPS files. - Copyright (C) 2005 Tobias Minich, robertlipe@usa.net + Copyright (C) 2005 Tobias Minich, Based on the Cetus I/O Filter, Copyright (C) 2002 Robert Lipe, robertlipe@usa.net @@ -22,25 +22,32 @@ */ + #include "defs.h" +#if PDBFMTS_ENABLED #include "csv_util.h" #include "coldsync/palm.h" #include "coldsync/pdb.h" +#include "grtcirc.h" #define MYNAME "cotoGPS" + #define MYTYPETRACK 0x5452434b /* TRCK */ #define MYTYPEWPT 0x44415441 /* DATA */ -#define MYCREATOR 0x636f4750 /* coGP */ +#define MYCREATOR 0x636f4750 /* coGP */ #define NOTESZ 4096 #define DESCSZ 4096 +#define MAX_MARKER_NAME_LENGTH 20 +#define CATEGORY_NAME_LENGTH 16 + typedef enum { - cotofixNone = 0, /* No Fix or Warning */ + cotofixNone = 0, /* No Fix or Warning */ cotofixReserved = 1, /* Shouldn't occur*/ - cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ - cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ - cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ + cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ + cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ + cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ } fix_quality; struct record_track { @@ -54,21 +61,21 @@ struct record_track { word alt; /* Altitude */ /* accuracy and precision information for use where applicable */ - uword hdop; /* _dop * 10 */ - uword vdop; - uword pdop; + gbuint16 hdop; /* _dop * 10 */ + gbuint16 vdop; + gbuint16 pdop; ubyte sat_tracked; ubyte fix_quality; - uword speed; /* *10 */ - udword time; /* Palm Time */ + gbuint16 speed; /* *10 */ + gbuint32 time; /* Palm Time */ }; -#define MAX_MARKER_NAME_LENGTH 20 struct record_wpt { char lon[8]; char lat[8]; char name[MAX_MARKER_NAME_LENGTH]; + char notes[1]; }; @@ -76,30 +83,33 @@ struct record_wpt { typedef char appinfo_category[16]; -#define APPINFO_PACKED_SIZE sizeof(uword)+16*sizeof(appinfo_category)+17*sizeof(ubyte) -struct appinfo { - uword renamedCategories; - appinfo_category categories[16]; +typedef struct appinfo { + ubyte U0; + ubyte renamedCategories; + appinfo_category categories[CATEGORY_NAME_LENGTH]; ubyte ids[16]; ubyte maxid; -}; +} appinfo_t; + +#define APPINFO_SIZE sizeof(appinfo_t) static FILE *file_in; static FILE *file_out; static const char *out_fname; static const char *in_fname; /* We might need that for naming tracks */ -struct pdb *opdb; +static struct pdb *opdb; +static short_handle mkshort_wr_handle; -static char *trackname = NULL; static char *zerocat = NULL; static char *internals = NULL; static arglist_t coto_args[] = { - {"trackname", &trackname, "Track name", NULL, ARGTYPE_STRING }, - {"zerocat", &zerocat, "Name of the 'unassigned' category.", NULL, ARGTYPE_STRING }, - {"internals", &internals, "Export some internal stuff to notes.", NULL, ARGTYPE_STRING|ARGTYPE_HIDDEN }, - {0, 0, 0, 0, 0 } + {"zerocat", &zerocat, "Name of the 'unassigned' category", NULL, + ARGTYPE_STRING, ARG_NOMINMAX }, + {"internals", &internals, "Export some internal stuff to notes", NULL, + ARGTYPE_STRING | ARGTYPE_HIDDEN, ARG_NOMINMAX }, + ARG_TERMINATOR }; static void @@ -113,10 +123,6 @@ static void rd_deinit(void) { fclose(file_in); - if ( trackname ) { - xfree(trackname); - trackname = NULL; - } } static void @@ -130,10 +136,24 @@ static void wr_deinit(void) { fclose(file_out); - if ( trackname ) { - xfree(trackname); - trackname = NULL; +} + +/* helpers */ + +static char * +coto_get_icon_descr(int category, const appinfo_t *app) +{ + char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned"; + if ((category >= 0) && (category < 16)) + { + if ((category > 0) && (app->categories[category][0] == '\0')) + category = 0; + + strncpy(buff, app->categories[category], sizeof(buff) - 1); + if (buff[0] == '\0') + return NULL; } + return xstrdup(buff); } static void @@ -142,43 +162,48 @@ coto_track_read(struct pdb *pdb) struct record_track *rec; struct pdb_record *pdb_rec; route_head *trk_head; - char *loctrackname = NULL; + char *track_name; - if (trackname) - // Given by user - loctrackname = xstrdup(trackname); - else if (strncmp(pdb->name, "cotoGPS TrackDB", PDB_DBNAMELEN)) + if (strncmp(pdb->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0) // Use database name if not default - loctrackname = xstrndup(pdb->name, PDB_DBNAMELEN); + track_name = xstrndup(pdb->name, PDB_DBNAMELEN); else { - // Use filename - const char *fnametmp = strrchr(in_fname, '/'); // FIXME: Don't know if this works on Windows + // Use filename for new track title + const char *fnametmp = strrchr(in_fname, '/'); + if (fnametmp == NULL) + fnametmp = strrchr(in_fname, '\\'); if (fnametmp) fnametmp++; else fnametmp = in_fname; - loctrackname = xstrndup(fnametmp, strrchr(fnametmp,'.')-fnametmp); + if (strrchr(fnametmp, '.') != NULL) + track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp); + else + track_name = xstrdup(fnametmp); } trk_head = route_head_alloc(); track_add_head(trk_head); - trk_head->rte_name = loctrackname; + trk_head->rte_name = track_name; - for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { + for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) + { waypoint *wpt_tmp; wpt_tmp = waypt_new(); rec = (struct record_track *) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->latitude)); - wpt_tmp->longitude = -pdb_read_double(&rec->longitude)*360.0/(2.0*M_PI); - wpt_tmp->latitude = pdb_read_double(&rec->latitude)*360.0/(2.0*M_PI); // It's not the course, so leave it out for now // wpt_tmp->course = pdb_read_double(&rec->arc); wpt_tmp->altitude = be_read16(&rec->alt); - if (internals) { + if (internals) + { // Parse the option as xcsv delimiter const char *inter = xcsv_get_char_from_constant_table(internals); char temp[256]; @@ -191,20 +216,33 @@ coto_track_read(struct pdb *pdb) wpt_tmp->hdop = be_read16(&rec->hdop)/10.0; wpt_tmp->vdop = be_read16(&rec->vdop)/10.0; wpt_tmp->sat = rec->sat_tracked; - switch (rec->fix_quality) { - case cotofixNone: wpt_tmp->fix = fix_none; break; - case cotofixReserved: wpt_tmp->fix = fix_unknown; break; - case cotofix2D: wpt_tmp->fix = fix_2d; break; - case cotofix3D: wpt_tmp->fix = fix_3d; break; - case cotofixDGPS: wpt_tmp->fix = fix_dgps; break; + switch (rec->fix_quality) + { + case cotofixNone: + wpt_tmp->fix = fix_none; + break; + case cotofixReserved: + wpt_tmp->fix = fix_unknown; + break; + case cotofix2D: + wpt_tmp->fix = fix_2d; + break; + case cotofix3D: + wpt_tmp->fix = fix_3d; + break; + case cotofixDGPS: + wpt_tmp->fix = fix_dgps; + break; } wpt_tmp->speed = be_read16(&rec->speed)/10.0; - wpt_tmp->creation_time = be_read32(&rec->time) - 2082844800U; - - route_add_wpt(trk_head, wpt_tmp); - + rec->time = be_read32(&rec->time); + if (rec->time != 0) + { + rec->time -= 2082844800U; + wpt_tmp->creation_time = rec->time; + } + track_add_wpt(trk_head, wpt_tmp); } - } static void @@ -212,42 +250,34 @@ coto_wpt_read(struct pdb *pdb) { struct record_wpt *rec; struct pdb_record *pdb_rec; - char *vdata; - struct appinfo *app; - + appinfo_t *app; app = (struct appinfo *) pdb->appinfo; - for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { + for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) + { waypoint *wpt_tmp; - int c=-1; + char *c; wpt_tmp = waypt_new(); rec = (struct record_wpt *) pdb_rec->data; - // Find category - /* I thought this would be the proper way. Leaving it in in case it becomes the proper one =) - for(i=0;i<16;i++) - if (app->ids[i] == pdb_rec->category) {c=i; break;} - */ - c = pdb_rec->category; + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->lon)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->lat)); - wpt_tmp->longitude = -pdb_read_double(&rec->lon)*360.0/(2.0*M_PI); - wpt_tmp->latitude = pdb_read_double(&rec->lat)*360.0/(2.0*M_PI); + wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name)); - wpt_tmp->shortname = xstrdup((char *) &rec->name); - wpt_tmp->description = xstrdup((char *) &rec->name); - - if (c>0) - wpt_tmp->icon_descr = xstrndup(app->categories[c], 16); - else if (c<0) - wpt_tmp->icon_descr = xstrdup("Unknown"); + wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app); if (wpt_tmp->icon_descr) wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - - if (pdb_rec->data_len>sizeof(*rec)) { - vdata = (char *) pdb_rec->data + sizeof(*rec); - wpt_tmp->notes = xstrdup(vdata); + + if ((c = strstr(rec->notes, "\nNotes:\n"))) { /* remove our contruct */ + wpt_tmp->notes = xstrdup(c + 8); + if (c != rec->notes) { + wpt_tmp->description = xstrndup(rec->notes, c - rec->notes); + } + } else { + wpt_tmp->notes = xstrdup(rec->notes); } waypt_add(wpt_tmp); @@ -268,14 +298,18 @@ data_read(void) fatal(MYNAME ": Not a cotoGPS file.\n"); } - if (pdb->version > 0) { - fatal(MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); - } + is_fatal((pdb->version > 0), + MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); - if (pdb->type == MYTYPETRACK) - coto_track_read(pdb); - if (pdb->type == MYTYPEWPT) - coto_wpt_read(pdb); + switch(pdb->type) + { + case MYTYPETRACK: + coto_track_read(pdb); + break; + case MYTYPEWPT: + coto_wpt_read(pdb); + break; + } free_pdb(pdb); } @@ -292,8 +326,8 @@ coto_prepare_wpt_write(struct pdb *opdb) strncpy(opdb->name, "cotoGPS MarkerDB", PDB_DBNAMELEN); - opdb->appinfo_len = APPINFO_PACKED_SIZE; - opdb->appinfo = calloc(APPINFO_PACKED_SIZE,1); + opdb->appinfo_len = APPINFO_SIZE; + opdb->appinfo = calloc(APPINFO_SIZE,1); ai = (struct appinfo *) opdb->appinfo; be_write16(&ai->renamedCategories, 31); // Don't ask me why... @@ -311,11 +345,9 @@ coto_wpt_write(const waypoint *wpt) struct appinfo *ai = (struct appinfo *) opdb->appinfo; static int ct; struct pdb_record *opdb_rec; - static void *mkshort_wr_handle; char *notes = NULL; char *shortname = NULL; - char *vdata; - int size = sizeof(*rec); + int size; ubyte cat = 0; int i; @@ -323,44 +355,51 @@ coto_wpt_write(const waypoint *wpt) setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH); setshort_whitespace_ok(mkshort_wr_handle, 1); - if ((global_opts.synthesize_shortnames && wpt->description) || (!wpt->shortname)) + if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL)) shortname = mkshort_from_wpt(mkshort_wr_handle, wpt); else shortname = xstrdup(wpt->shortname); - if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) { - if ((wpt->notes) && (strcmp(wpt->description, wpt->notes))) { - size+=strlen(wpt->description)+strlen(wpt->notes)+9; - notes = xcalloc(strlen(wpt->description)+strlen(wpt->notes)+9,1); - sprintf(notes,"%s\nNotes:\n%s", wpt->description, wpt->notes); + if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) + { + if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) + { + notes = xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1); + sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes); } else { - size+=strlen(wpt->description)+1; notes = xstrdup(wpt->description); } - } else if (wpt->notes) { - size+=strlen(wpt->notes)+1; + } + else if (wpt->notes != NULL) + { notes = xstrdup(wpt->notes); } - rec = xcalloc(size,1); - pdb_write_double(&rec->lon, -2.0*M_PI*wpt->longitude/360.0); - pdb_write_double(&rec->lat, 2.0*M_PI*wpt->latitude/360.0); - snprintf((char *) &rec->name, MAX_MARKER_NAME_LENGTH, "%s", shortname); + + size = sizeof(*rec); + if (notes != NULL) + size += strlen(notes); + rec = xcalloc(size, 1); + + pdb_write_double(&rec->lon, RAD(-wpt->longitude)); + pdb_write_double(&rec->lat, RAD(wpt->latitude)); + strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH); - if (notes) { - vdata = (char *) rec + sizeof(*rec); - strcpy(vdata, notes); + if (notes) + { + strcpy(rec->notes, notes); xfree(notes); } - if (wpt->icon_descr) { - for(i=1;i<16;i++) + if (wpt->icon_descr) + { + for(i = 1; i < 16; i++) if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) {cat=i; break;} if (!cat) { // We have a new one if (ai->maxid<15) { i = ++ai->maxid; snprintf(ai->categories[i], 16, "%s", wpt->icon_descr); - cat=ai->ids[i]=i; + cat = ai->ids[i] = i; } else { // We're full! warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned"); @@ -370,18 +409,16 @@ coto_wpt_write(const waypoint *wpt) opdb_rec = new_Record (0, cat, ct++, size, (const ubyte *)rec); - if (opdb_rec == NULL) { + if (opdb_rec == NULL) fatal(MYNAME ": libpdb couldn't create record\n"); - } - if (pdb_AppendRecord(opdb, opdb_rec)) { + if (pdb_AppendRecord(opdb, opdb_rec)) fatal(MYNAME ": libpdb couldn't append record\n"); - } + xfree(shortname); xfree(rec); - mkshort_del_handle(mkshort_wr_handle); - + mkshort_del_handle(&mkshort_wr_handle); } static void @@ -392,9 +429,14 @@ data_write(void) } coto_prepare_wpt_write(opdb); + waypt_disp_all(coto_wpt_write); + /* + if we want waypoints from all data, we should create a new filter for that + track_disp_all(NULL, NULL, coto_wpt_write); route_disp_all(NULL, NULL, coto_wpt_write); + */ pdb_Write(opdb, fileno(file_out)); @@ -412,4 +454,6 @@ ff_vecs_t coto_vecs = { data_write, NULL, coto_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/cst.c b/cst.c new file mode 100644 index 000000000..34f9b44d4 --- /dev/null +++ b/cst.c @@ -0,0 +1,362 @@ +/* + + Support for CarteSurTable data file, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include "strptime.h" +#include +#include +#include +#include + +#define MYNAME "cst" + +#undef CST_DEBUG + +#define CST_UNKNOWN 0 +#define CST_HEADER 1 +#define CST_ROUTE 2 +#define CST_NOTES 3 +#define CST_REFERENCE 4 +#define CST_VERSION 5 + +static gbfile *fin; + +static route_head *temp_route; + +/* placeholders for options */ + +static +arglist_t cst_args[] = { + ARG_TERMINATOR +}; + +/* helpers */ + +static void +cst_add_wpt(const route_head *track, waypoint *wpt) +{ + if ((wpt == NULL) || (track == NULL)) return; + + if (wpt->shortname != NULL) + { + waypt_add(waypt_dupe(wpt)); + if (wpt->url != NULL) + { + xfree(wpt->url); + wpt->url = NULL; + } + + if (temp_route == NULL) + { + temp_route = route_head_alloc(); + route_add_head(temp_route); + } + route_add_wpt(temp_route, waypt_dupe(wpt)); + } + track_add_wpt((route_head *)track, (waypoint *)wpt); +} + +static char * +cst_make_url(char *str) +{ + int len = strlen(str); + char *res; + + if (len < 3) return NULL; + + if (strstr(str, "://") > str) + return xstrdup(str); + else if (strstr(str, ":\\") == str+1) /* DOS 0.01++ file format */ + { + res = xstrdup("file://*:"); + res[7] = *str++; + res[8] = *str++; + res = xstrappend(res, str); + { + char *c; + int i; + + c = res; /* replace all backslashes with a slash */ + while ((c = strchr(c, '\\'))) *c++ = '/'; + + c = res; /* enumerate number of spaces within filename */ + i = 0; + while ((c = strchr(c, ' '))) + { + c++; + i++; + } + + if (i > 0) /* .. and replace them with "%20" */ + { + char *src, *dest, *last; + + last = src = res; + res = dest = xcalloc(strlen(src) + (2*i) + 1, 1); + while ((c = strchr(src, ' '))) + { + if (c != src) strncpy(dest, src, c - src); + strcat(dest, "%20"); + c++; + src = c; + dest = res + strlen(res); + } + while (*src != '\0') + *dest++ = *src++; + xfree(last); + } + } + return res; + + } + else + return NULL; + +} + +/* --------------------------------------------------------------------------- */ + +static void +cst_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + temp_route = NULL; +} + +static void +cst_rd_deinit(void) +{ + gbfclose(fin); +} + +/* --------------------------------------------------------------------------- */ + +static void +cst_data_read(void) +{ + char *buff; + int line = 0; + int data_lines = -1; + int line_of_count = -1; + int valid = 0; + int section = CST_UNKNOWN; + int cst_version; + int cst_points = -1; + route_head *track = NULL; + waypoint *wpt = NULL; + + while ((buff = gbfgetstr(fin))) + { + char *cin = buff; + + line++; + cin = lrtrim(buff); + if (strlen(cin) == 0) continue; + + if (strncmp(cin, "; ", 2) == 0) continue; + if (*cin == '#') + { + section = CST_UNKNOWN; + if (strcmp(cin+1, "ROUTE") == 0) section = CST_ROUTE; + else if (strcmp(cin+1, "VERSION") == 0) section = CST_VERSION; + else if (strcmp(cin+1, "NOTES") == 0) section = CST_NOTES; + else if (strcmp(cin+1, "REFERENCE") == 0) section = CST_REFERENCE; + else if (strcmp(cin+1, "CARTE SUR TABLE DATA FILE") == 0) + { + section = CST_HEADER; + valid = 1; + } + else + warning(MYNAME ": Unknown section \"%s\".\n", cin+1); + + continue; + } + + if (valid == 0) continue; + + switch(section) + { + case CST_ROUTE: + if (*cin == ';') + { + int data = 0; + + if (*(cin+1) != '\xA4') continue; + + if (strncmp(cin + 2, "bitmap", 6) == 0) + { + cin = lrtrim(cin + 8); + if (*cin != '\0') + wpt->url = cst_make_url(cin); + } + + while ((buff = gbfgetstr(fin))) + { + line++; + cin = lrtrim(buff); + + if (strcmp(cin + 2, "note") == 0) + { + buff = gbfgetstr(fin); + if (buff == NULL) buff = ""; + line++; + cin = lrtrim(buff); + if (*cin != '\0') + wpt->notes = xstrdup(cin); + } + else if (strcmp(cin + 2, "end") == 0) + { + data = 1; + break; + } + } + if (data == 0) + fatal(MYNAME ": Unexpected end of file!\n"); + } + else + { + int interp, i; + char name[256]; + char *pow; + + if (data_lines < 0) + { + if ((2 != sscanf(cin, "%d %128s", &i, name)) || + (case_ignore_strcmp(name, "Points") != 0)) + fatal(MYNAME "-line %d: Number of points expected!\n", line); + line_of_count = line; + data_lines = 0; + cst_points = i; + continue; + } + + cst_add_wpt(track, wpt); + wpt = NULL; + + + wpt = waypt_new(); + + if (5 != sscanf(cin, "%lf %lf %lf %d %s", + &wpt->longitude, + &wpt->latitude, + &wpt->altitude, + &interp, name)) + { + fatal(MYNAME ": Could not interprete line %d!\n", line); + } + + data_lines++; + + if (strcmp(name, "1") == 0) + { + track = route_head_alloc(); + track_add_head(track); + } + else if (strncmp(name, "NAME:", 5) == 0) + wpt->shortname = xstrdup(((char *)&name) + 5); + + pow = strrchr(cin, '^'); + if (pow != NULL) + { + struct tm tm; + + pow = lrtrim(++pow); + strptime(pow, "%Y %m %d %H:%M:%S", &tm); + + wpt->creation_time = mkgmtime(&tm); + } + wpt->latitude /= 100000.0; + wpt->longitude /= 100000.0; + } + break; + + + case CST_VERSION: + cst_version = atoi(cin); + if (cst_version != 40) + warning(MYNAME ": Not tested with file version %d.\n", cst_version); + break; + + case CST_REFERENCE: + if ((strncmp(cin, "DATUM ", 6) == 0) && (strstr(cin, "WGS 84") == NULL)) + fatal(MYNAME ": Unsupported datum (%s)!\n", cin); + break; + + case CST_HEADER: + case CST_NOTES: + break; + } + } + cst_add_wpt(track, wpt); + wpt = NULL; + + if ((cst_points >= 0) && (data_lines != cst_points)) + warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points); +} + +#if 0 +static void +cst_wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); +} + +static void +cst_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +cst_route_hdr(const route_head *rte) +{ +} + +static void +cst_route_tlr(const route_head *rte) +{ +} + +static void +cst_write_wpt(const waypoint *wpt) +{ +} + +static void +cst_data_write(void) +{ +} +#endif + +ff_vecs_t cst_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + cst_rd_init, + NULL, /* cst_wr_init, */ + cst_rd_deinit, + NULL, /* cst_wr_deinit, */ + cst_data_read, + NULL, /* cst_data_write, */ + NULL, + cst_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +}; diff --git a/csv_util.c b/csv_util.c index 263d4f95c..e0817d44c 100644 --- a/csv_util.c +++ b/csv_util.c @@ -38,10 +38,15 @@ #define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0) #define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0) + +/****************************************************************************/ +/* obligatory global struct */ +/****************************************************************************/ +xcsv_file_t xcsv_file; + extern char *xcsv_urlbase; extern char *prefer_shortnames; -extern const char *gs_get_container(geocache_container t); extern geocache_type gs_mktype(const char *t); extern geocache_container gs_mkcont(const char *t); @@ -85,8 +90,10 @@ csv_stringclean(const char *string, const char *chararray) /* we don't want this character! */ memmove(p1, p1 + 1, (p2 - p1)); p1[p2 - p1] = '\0'; + p2--; } - p1++; + else + p1++; } cp++; } @@ -141,7 +148,7 @@ csv_stringtrim(const char *string, const char *enclosure, int strip_max) if (elen) { while ( (stripped < strip_max) && - ((size_t) (p2 - p1) >= elen) && + ((size_t) (p2 - p1 + 1) >= (elen * 2)) && (strncmp(p1, enclosure, elen) == 0) && (strncmp((p2 - elen + 1), enclosure, elen) == 0)) { p2 -= elen; @@ -173,7 +180,7 @@ csv_lineparse(const char *stringstart, const char *delimited_by, const char *sp; static const char *p = NULL; static char *tmp = NULL; - size_t dlen = 0, elen = 0; + size_t dlen = 0, elen = 0, efound = 0; int enclosedepth = 0; short int dfound; short int hyper_whitespace_delimiter = 0; @@ -215,15 +222,18 @@ csv_lineparse(const char *stringstart, const char *delimited_by, dlen = strlen(delimited_by); if (enclosed_in) elen = strlen(enclosed_in); - dfound = 0; while ((*p) && (!dfound)) { - if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) { + if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) + { + efound = 1; + p+=elen; if (enclosedepth) enclosedepth--; else enclosedepth++; + continue; } if (!enclosedepth) { @@ -237,6 +247,9 @@ csv_lineparse(const char *stringstart, const char *delimited_by, p++; } } + else { + p++; + } } /* allocate enough space for this data field */ @@ -245,6 +258,12 @@ csv_lineparse(const char *stringstart, const char *delimited_by, strncpy(tmp, sp, (p - sp)); tmp[p - sp] = '\0'; + if (elen && efound) { + char *c = csv_stringtrim(tmp, enclosed_in, 0); + xfree(tmp); + tmp = c; + } + if (dfound) { /* skip over the delimited_by */ p += dlen; @@ -258,10 +277,10 @@ csv_lineparse(const char *stringstart, const char *delimited_by, ": Warning- Unbalanced Field Enclosures (%s) on line %d\n", enclosed_in, line_no); } - return (tmp); } +#if CSVFMTS_ENABLED /*****************************************************************************/ /* dec_to_intdeg() - convert decimal degrees to integer degreees */ /* usage: i = dec_to_intdeg(31.1234, 1); */ @@ -333,7 +352,7 @@ decdir_to_dec(const char * decdir) return(rval * sign); } - +#endif /***************************************************************************** * human_to_dec() - convert a "human-readable" lat and/or lon to decimal @@ -343,7 +362,7 @@ decdir_to_dec(const char * decdir) * which: 0-no preference 1-prefer lat 2-prefer lon *****************************************************************************/ -static void +void human_to_dec( const char *instr, double *outlat, double *outlon, int which ) { double unk[3] = {999,999,999}; @@ -356,9 +375,19 @@ human_to_dec( const char *instr, double *outlat, double *outlon, int which ) const char *cur; double *numres = unk; int numind = 0; + char *buff; - cur = instr; - + if (strchr(instr, ',') != NULL) { + char *c; + buff = xstrdup(instr); + while ((c = strchr(buff, ','))) *c = '.'; + } + else { + buff = (char *)instr; + } + + cur = buff; + while ( cur && *cur ) { switch (*cur) { case 'n': case 's': case 'N': case 'S': @@ -404,9 +433,10 @@ human_to_dec( const char *instr, double *outlat, double *outlon, int which ) cur++; break; case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': case '.': + case '6': case '7': case '8': case '9': case '0': + case '.': case ',': numres[numind] = atof(cur); - while (cur && *cur && strchr("1234567890.",*cur)) cur++; + while (cur && *cur && strchr("1234567890.,",*cur)) cur++; break; case '-': unksign = -1; @@ -448,8 +478,12 @@ human_to_dec( const char *instr, double *outlat, double *outlon, int which ) if ( lon[2] != 999 ) *outlon += lon[2]/3600.0; if ( lonsign ) *outlon *= lonsign; } + if (buff != instr) { + xfree(buff); + } } +#if CSVFMTS_ENABLED /* * dec_to_human - convert decimal degrees to human readable */ @@ -575,13 +609,14 @@ xcsv_ifield_add(char *key, char *val, char *pfc) /* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf") */ /*****************************************************************************/ void -xcsv_ofield_add(char *key, char *val, char *pfc) +xcsv_ofield_add(char *key, char *val, char *pfc, int options) { field_map_t *fmp = xcalloc(sizeof(*fmp), 1); fmp->key = key; fmp->val = val; fmp->printfc = pfc; + fmp->options = options; ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); xcsv_file.ofield_ct++; @@ -641,7 +676,9 @@ static time_t sscanftime( const char *s, const char *format, const int gmt ) { - struct tm stm = {0,0,0,0,0,0,0,0,0}; + struct tm stm; + memset(&stm, 0, sizeof(stm)); + if ( strptime( s, format, &stm ) ) { stm.tm_isdst = -1; @@ -662,10 +699,17 @@ addhms( const char *s, const char *format ) int min =0; int sec =0; char * ampm = NULL; + int ac; ampm = xmalloc( strlen(s) ); - if (sscanf(s, format, &hour, &min, &sec, ampm)) + ac = sscanf(s, format, &hour, &min, &sec, &m); + /* If no time format in arg string, assume AM */ + if (ac < 4) { + ampm[0] = 0; + } + if (ac) { tt = ((tolower(ampm[0])=='P')?43200:0)+3600*hour+60*min+sec; + } xfree(ampm); return tt; @@ -685,6 +729,8 @@ writetime(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) return strftime(buff, bufsize, format, stmp ); } +#if 0 +/* not used */ static int writeisotime(char * buff, size_t bufsize, const char * format, time_t t) @@ -700,6 +746,7 @@ writeisotime(char * buff, size_t bufsize, const char * format, time_t t) xfree(ibuff); return i; } +#endif static @@ -739,6 +786,10 @@ time_to_yyyymmdd(time_t t) static void xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) { + char *enclosure = ""; + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + enclosure = "\""; + } if (strcmp(fmp->key, "IGNORE") == 0) { /* IGNORE -- Categorically ignore this... */ } else @@ -752,10 +803,10 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) /* IGNORE -- Calculated Sequence # For Ouput*/ } else if (strcmp(fmp->key, "SHORTNAME") == 0) { - wpt->shortname = csv_stringtrim(s, "", 0); + wpt->shortname = csv_stringtrim(s, enclosure, 0); } else if (strcmp(fmp->key, "DESCRIPTION") == 0) { - wpt->description = csv_stringtrim(s, "", 0); + wpt->description = csv_stringtrim(s, enclosure, 0); } else if (strcmp(fmp->key, "NOTES") == 0) { wpt->notes = csv_stringtrim(s, "", 0); @@ -789,7 +840,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); } else if ( strcmp(fmp->key, "LAT_NMEA") == 0) { - wpt->latitude = ddmm2degrees(wpt->latitude); + wpt->latitude = ddmm2degrees(atof(s)); } else /* LONGITUDE CONVERSIONS ***********************************************/ if (strcmp(fmp->key, "LON_DECIMAL") == 0) { @@ -809,7 +860,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); } else if ( strcmp(fmp->key, "LON_NMEA") == 0) { - wpt->latitude = ddmm2degrees(wpt->longitude); + wpt->longitude = ddmm2degrees(atof(s)); } else /* LAT AND LON CONVERSIONS ********************************************/ if ( strcmp(fmp->key, "LATLON_HUMAN_READABLE") == 0) { @@ -826,7 +877,7 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) /* ALTITUDE CONVERSIONS ************************************************/ if (strcmp(fmp->key, "ALT_FEET") == 0) { /* altitude in feet as a decimal value */ - wpt->altitude = atof(s) * .3048; + wpt->altitude = FEET_TO_METERS(atof(s)); } else if (strcmp(fmp->key, "ALT_METERS") == 0) { /* altitude in meters as a decimal value */ @@ -926,6 +977,12 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) if ( strcmp( fmp->key, "PATH_DISTANCE_MILES") == 0) { /* Ignored on input */ } else + if ( strcmp( fmp->key, "HEART_RATE") == 0) { + wpt->heartrate = atoi(s); + } else + if ( strcmp( fmp->key, "CADENCE") == 0) { + wpt->cadence = atoi(s); + } else if ( strcmp( fmp->key, "PATH_DISTANCE_KM") == 0 ) { /* Ignored on input */ } else { @@ -940,20 +997,17 @@ xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp) void xcsv_data_read(void) { - char buff[8192]; + char *buff; char *s; waypoint *wpt_tmp; int linecount = 0; queue *elem, *tmp; field_map_t *fmp; ogue_t *ogp; - - do { + + while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { linecount++; - memset(buff, '\0', sizeof(buff)); - fgets(buff, sizeof(buff), xcsv_file.xcsvfp); - - rtrim(buff); + buff = lrtrim(buff); /* skip over x many lines on the top for the prologue... */ if ((xcsv_file.prologue_lines) && ((linecount - 1) < @@ -1006,7 +1060,7 @@ xcsv_data_read(void) waypt_add(wpt_tmp); } - } while (!feof(xcsv_file.xcsvfp)); + } } static void @@ -1034,8 +1088,8 @@ xcsv_waypt_pr(const waypoint *wpt) queue *elem, *tmp; if ( oldlon < 900 ) { - pathdist += tomiles(gcdist(oldlat*M_PI/180,oldlon*M_PI/180, - wpt->latitude*M_PI/180,wpt->longitude*M_PI/180)); + pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), + RAD(wpt->latitude),RAD(wpt->longitude))); } oldlon = wpt->longitude; oldlat = wpt->latitude; @@ -1075,17 +1129,32 @@ xcsv_waypt_pr(const waypoint *wpt) description = shortname; } else if (description) { char *odesc = description; - description = str_utf8_to_ascii(odesc); + description = xstrdup(odesc); xfree(odesc); } i = 0; QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { char *obuff; + double lat = wpt->latitude; + double lon = wpt->longitude; + /* + * A klunky concept. This should evaluate to true for any + * field if we think we don't have realistic value for it. + * This is used by the 'optional' attribute for suppressing + * fields on output. + */ + int field_is_unknown = 0; + fmp = (field_map_t *) elem; - if (i != 0) - fprintf (xcsv_file.xcsvfp, write_delimiter); + if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) + gbfprintf (xcsv_file.xcsvfp, write_delimiter); + + if (fmp->options & OPTIONS_ABSOLUTE) { + lat = fabs(lat); + lon = fabs(lon); + } i++; #define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) @@ -1160,83 +1229,83 @@ xcsv_waypt_pr(const waypoint *wpt) /* LATITUDE CONVERSION***********************************************/ if (strcmp(fmp->key, "LAT_DECIMAL") == 0) { /* latitude as a pure decimal value */ - writebuff(buff, fmp->printfc, wpt->latitude); + writebuff(buff, fmp->printfc, lat); } else if (strcmp(fmp->key, "LAT_DECIMALDIR") == 0) { /* latitude as a decimal value with N/S after it */ - snprintf(buff, sizeof(buff), fmp->printfc, fabs(wpt->latitude), - LAT_DIR(wpt->latitude)); + snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), + LAT_DIR(lat)); } else if (strcmp(fmp->key, "LAT_DIRDECIMAL") == 0) { /* latitude as a decimal value with N/S before it */ snprintf(buff, sizeof(buff), fmp->printfc, - LAT_DIR(wpt->latitude), - fabs(wpt->latitude)); + LAT_DIR(lat), + fabs(lat)); } else if (strcmp(fmp->key, "LAT_INT32DEG") == 0) { /* latitude as an integer offset from 0 degrees */ writebuff(buff, fmp->printfc, - dec_to_intdeg(wpt->latitude, 1)); + dec_to_intdeg(lat, 1)); } else if (strcmp(fmp->key, "LAT_HUMAN_READABLE") == 0) { - dec_to_human( buff, fmp->printfc, "SN", wpt->latitude ); + dec_to_human( buff, fmp->printfc, "SN", lat ); } else if (strcmp(fmp->key, "LAT_NMEA") == 0) { - writebuff(buff, fmp->printfc, degrees2ddmm(wpt->latitude)); + writebuff(buff, fmp->printfc, degrees2ddmm(lat)); } else /* LONGITUDE CONVERSIONS*********************************************/ if (strcmp(fmp->key, "LON_DECIMAL") == 0) { /* longitude as a pure decimal value */ - writebuff(buff, fmp->printfc, wpt->longitude); + writebuff(buff, fmp->printfc, lon); } else if (strcmp(fmp->key, "LON_DECIMALDIR") == 0) { /* latitude as a decimal value with N/S after it */ snprintf(buff, sizeof(buff), fmp->printfc, - fabs(wpt->longitude), - LON_DIR(wpt->longitude)); + fabs(lon), + LON_DIR(lon)); } else if (strcmp(fmp->key, "LON_DIRDECIMAL") == 0) { /* latitude as a decimal value with N/S before it */ snprintf(buff, sizeof(buff), fmp->printfc, - LON_DIR(wpt->longitude), - fabs(wpt->longitude)); + LON_DIR(lon), + fabs(lon)); } else if (strcmp(fmp->key, "LON_INT32DEG") == 0) { /* longitudee as an integer offset from 0 degrees */ writebuff(buff, fmp->printfc, - dec_to_intdeg(wpt->longitude, 0)); + dec_to_intdeg(lon, 0)); } else if (strcmp(fmp->key, "LON_HUMAN_READABLE") == 0) { - dec_to_human( buff, fmp->printfc, "WE", wpt->longitude ); + dec_to_human( buff, fmp->printfc, "WE", lon ); } else if (strcmp(fmp->key, "LATLON_HUMAN_READABLE") == 0) { - dec_to_human( buff, fmp->printfc, "SN", wpt->latitude ); + dec_to_human( buff, fmp->printfc, "SN", lat ); if ( !isspace(buff[strlen(buff)])) strcat( buff, " " ); dec_to_human( buff+strlen(buff), fmp->printfc, "WE", - wpt->longitude ); + lon ); } else if (strcmp(fmp->key, "LON_NMEA") == 0) { - writebuff(buff, fmp->printfc, degrees2ddmm(wpt->longitude)); + writebuff(buff, fmp->printfc, degrees2ddmm(lon)); } else /* DIRECTIONS *******************************************************/ if (strcmp(fmp->key, "LAT_DIR") == 0) { /* latitude N/S as a char */ writebuff(buff, fmp->printfc, - LAT_DIR(wpt->latitude)); + LAT_DIR(lat)); } else if (strcmp(fmp->key, "LON_DIR") == 0) { /* longitude E/W as a char */ writebuff(buff, fmp->printfc, - LON_DIR(wpt->longitude)); + LON_DIR(lon)); } else /* ALTITUDE CONVERSIONS**********************************************/ if (strcmp(fmp->key, "ALT_FEET") == 0) { /* altitude in feet as a decimal value */ writebuff(buff, fmp->printfc, - (wpt->altitude * 3.2808)); + METERS_TO_FEET(wpt->altitude)); } else if (strcmp(fmp->key, "ALT_METERS") == 0) { /* altitude in meters as a decimal value */ @@ -1260,6 +1329,14 @@ xcsv_waypt_pr(const waypoint *wpt) writebuff( buff, fmp->printfc, wpt->course ); } else + /* HEART RATE CONVERSION***********************************************/ + if (strcmp(fmp->key, "HEART_RATE") == 0) { + writebuff(buff, fmp->printfc, wpt->heartrate); + } else + /* CADENCE CONVERSION***********************************************/ + if (strcmp(fmp->key, "CADENCE") == 0) { + writebuff(buff, fmp->printfc, wpt->cadence); + } else /* TIME CONVERSIONS**************************************************/ if (strcmp(fmp->key, "EXCEL_TIME") == 0) { /* creation time as an excel (double) time */ @@ -1295,43 +1372,54 @@ xcsv_waypt_pr(const waypoint *wpt) if (strcmp(fmp->key, "GEOCACHE_DIFF") == 0) { /* Geocache Difficulty as a double */ writebuff(buff, fmp->printfc, wpt->gc_data.diff / 10.0); + field_is_unknown = !wpt->gc_data.diff; } else if (strcmp(fmp->key, "GEOCACHE_TERR") == 0) { /* Geocache Terrain as a double */ writebuff(buff, fmp->printfc, wpt->gc_data.terr / 10.0); + field_is_unknown = !wpt->gc_data.terr; } else if (strcmp(fmp->key, "GEOCACHE_CONTAINER") == 0) { /* Geocache Container */ writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data.container)); + field_is_unknown = wpt->gc_data.container == gc_unknown; } else if (strcmp(fmp->key, "GEOCACHE_TYPE") == 0) { /* Geocache Type */ writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data.type)); + field_is_unknown = wpt->gc_data.type == gt_unknown; } else if (strcmp(fmp->key, "GEOCACHE_HINT") == 0) { writebuff(buff, fmp->printfc, NONULL(wpt->gc_data.hint)); + field_is_unknown = !wpt->gc_data.hint; } else if (strcmp(fmp->key, "GEOCACHE_PLACER") == 0) { writebuff(buff, fmp->printfc, NONULL(wpt->gc_data.placer)); + field_is_unknown = !wpt->gc_data.placer; } else /* GPS STUFF *******************************************************/ if (strcmp(fmp->key, "GPS_HDOP") == 0) { writebuff(buff, fmp->printfc, wpt->hdop); + field_is_unknown = !wpt->hdop; } else if (strcmp(fmp->key, "GPS_VDOP") == 0) { writebuff(buff, fmp->printfc, wpt->vdop); + field_is_unknown = !wpt->vdop; } else if (strcmp(fmp->key, "GPS_PDOP") == 0) { writebuff(buff, fmp->printfc, wpt->pdop); + field_is_unknown = !wpt->pdop; } else if (strcmp(fmp->key, "GPS_SAT") == 0) { writebuff(buff, fmp->printfc, wpt->sat); + field_is_unknown = !wpt->sat; } else if (strcmp(fmp->key, "GPS_FIX") == 0) { char *fix = NULL; switch (wpt->fix) { case fix_unknown: + field_is_unknown = 1; fix = "Unknown"; break; case fix_none: @@ -1359,11 +1447,26 @@ xcsv_waypt_pr(const waypoint *wpt) obuff = csv_stringclean(buff, xcsv_file.badchars); - fprintf (xcsv_file.xcsvfp, "%s", obuff); + + if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { + goto next; + } + + + /* As a special case (pronounced "horrible hack") we allow + * ""%s"" to smuggle bad characters through. + */ + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + gbfprintf (xcsv_file.xcsvfp, "\"%s\"", obuff); + } else { + gbfprintf (xcsv_file.xcsvfp, "%s", obuff); + } + +next: xfree(obuff); } - fprintf (xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + gbfprintf (xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); if (description && description != shortname) xfree(description); @@ -1402,12 +1505,12 @@ xcsv_data_write(void) ol = strsub(ogp->val, "__FILE__", xcsv_file.fname); if (ol) { - fprintf(xcsv_file.xcsvfp, "%s", ol); + gbfprintf(xcsv_file.xcsvfp, "%s", ol); xfree(ol); } else { - fprintf(xcsv_file.xcsvfp, "%s", ogp->val); + gbfprintf(xcsv_file.xcsvfp, "%s", ogp->val); } - fprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); } waypt_disp_all(xcsv_waypt_pr); @@ -1417,7 +1520,7 @@ xcsv_data_write(void) /* output epilogue lines, if any. */ QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { ogp = (ogue_t *) elem; - fprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); + gbfprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); } } - +#endif diff --git a/csv_util.h b/csv_util.h index a4d2d4210..8da2d3e2a 100644 --- a/csv_util.h +++ b/csv_util.h @@ -30,6 +30,9 @@ CSV_STRINGTRIM(const char *string, const char *enclosure, int strip_max, DEBUG_P char * csv_lineparse(const char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no); +void +human_to_dec( const char *instr, double *outlat, double *outlon, int which ); + char * #ifndef DEBUG_MEM csv_stringclean(const char *string, const char *chararray); @@ -57,7 +60,7 @@ void xcsv_ifield_add(char *, char *, char *); void -xcsv_ofield_add(char *, char *, char *); +xcsv_ofield_add(char *, char *, char *, int options); void xcsv_destroy_style(void); @@ -70,11 +73,15 @@ xcsv_get_char_from_constant_table(char *key); /****************************************************************************/ /* something to map fields to waypts */ +#define OPTIONS_NODELIM 1 +#define OPTIONS_ABSOLUTE 2 +#define OPTIONS_OPTIONAL 3 typedef struct field_map { queue Q; char * key; char * val; char * printfc; + int options; } field_map_t; /* a queuing struct for prologues / epilogues */ @@ -116,13 +123,13 @@ typedef struct { int ifield_ct; /* actual # of ifields */ int ofield_ct; /* actual # of ofields */ - FILE * xcsvfp; /* ptr to current *open* data file */ + gbfile * xcsvfp; /* ptr to current *open* data file */ char * fname; /* ptr to filename of above. */ char * description; /* Description for help text */ char * extension; /* preferred filename extension (for wrappers)*/ - void * mkshort_handle; /* handle for mkshort() */ + short_handle mkshort_handle;/* handle for mkshort() */ ff_type type; /* format type for GUI wrappers. */ } xcsv_file_t; @@ -131,4 +138,4 @@ typedef struct { /****************************************************************************/ /* obligatory global struct */ /****************************************************************************/ -xcsv_file_t xcsv_file; +extern xcsv_file_t xcsv_file; diff --git a/defs.h b/defs.h index a0b5eeb62..3c2d5ad93 100644 --- a/defs.h +++ b/defs.h @@ -25,9 +25,23 @@ #include #include #include +#include "config.h" #include "queue.h" #include "gbtypes.h" - +#if HAVE_LIBZ +#include +#elif !ZLIB_INHIBITED +#include "zlib/zlib.h" +#endif +#include "gbfile.h" +#include "cet.h" +#include "cet_util.h" +#include "inifile.h" + +// Turn on Unicode in expat? +#ifdef _UNICODE +# define XML_UNICODE +#endif /* * Amazingly, this constant is not specified in the standard... @@ -39,6 +53,17 @@ #define FEET_TO_METERS(feetsies) ((feetsies) * 0.3048) #define METERS_TO_FEET(meetsies) ((meetsies) * 3.2808399) +#define NMILES_TO_METERS(a) ((a) * 1852.0) /* nautical miles */ +#define MILES_TO_METERS(a) ((a) * 1609.344) +#define METERS_TO_MILES(a) ((a) / 1609.344) +#define FATHOMS_TO_METERS(a) ((a) * 1.8288) + +#define CELSIUS_TO_FAHRENHEIT(a) (((a) * 1.8) + 32) +#define FAHRENHEIT_TO_CELSIUS(a) (((a) - 32) / 1.8) + +#define SECONDS_PER_HOUR (60L*60) +#define SECONDS_PER_DAY (24L*60*60) + /* * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in * C99 (albeit with slightly different semantics) but it isn't in C89. @@ -47,11 +72,36 @@ #if __WIN32__ # define snprintf _snprintf # define vsnprintf _vsnprintf +# ifndef fileno +# define fileno _fileno +# endif +# define strdup _strdup #endif /* Turn off numeric conversion warning */ #if __WIN32__ -#pragma warning(disable:4244) +# if _MSC_VER +# pragma warning(disable:4244) +# endif +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/* Pathname separator character */ +#if __WIN32__ +# define GB_PATHSEP '\\' +#else +# define GB_PATHSEP '/' +#endif + +/* + * Toss in some GNU C-specific voodoo for checking. + */ +#if __GNUC__ +# define PRINTFLIKE(x,y) __attribute__ ((__format__ (__printf__, (x), (y)))) +# define NORETURN void __attribute__ ((__noreturn__)) +#else +# define PRINTFLIKE(x,y) +# define NORETURN void #endif /* @@ -61,6 +111,14 @@ #define BASE_STRUCT(memberp, struct_type, member_name) \ ((struct_type *)((char *)(memberp) - offsetof(struct_type, member_name))) +typedef enum { + fix_unknown=-1, + fix_none=0, + fix_2d=1, + fix_3d, + fix_dgps, + fix_pps +} fix_type; /* * Define globally on which kind of data gpsbabel is working. @@ -70,28 +128,22 @@ typedef enum { trkdata = 1 , wptdata, - rtedata + rtedata, + posndata } gpsdata_type; -typedef enum { - fix_unknown=-1, - fix_none=0, - fix_2d=1, - fix_3d, - fix_dgps, - fix_pps -} fix_type; - #define NOTHINGMASK 0 #define WPTDATAMASK 1 #define TRKDATAMASK 2 #define RTEDATAMASK 4 +#define POSNDATAMASK 8 /* mask objective testing */ #define doing_nothing (global_opts.masked_objective == NOTHINGMASK) #define doing_wpts ((global_opts.masked_objective & WPTDATAMASK) == WPTDATAMASK) #define doing_trks ((global_opts.masked_objective & TRKDATAMASK) == TRKDATAMASK) #define doing_rtes ((global_opts.masked_objective & RTEDATAMASK) == RTEDATAMASK) +#define doing_posn ((global_opts.masked_objective & POSNDATAMASK) == POSNDATAMASK) typedef struct { int synthesize_shortnames; @@ -100,11 +152,16 @@ typedef struct { unsigned int masked_objective; int verbose_status; /* set by GUI wrappers for status */ int no_smart_icons; - int no_smart_names; + int no_smart_names; + cet_cs_vec_t *charset; + char *charset_name; + inifile_t *inifile; } global_options; extern global_options global_opts; extern const char gpsbabel_version[]; +extern time_t gpsbabel_now; /* gpsbabel startup-time; initialized in main.c with time() */ +extern time_t gpsbabel_time; /* gpsbabel startup-time; initialized in main.c with current_time(), ! ZERO within testo ! */ /* Short or Long XML Times */ #define XML_SHORT_TIME 1 @@ -127,7 +184,9 @@ typedef enum { gt_earth, gt_locationless, gt_benchmark, /* Extension to Groundspeak for GSAK */ - gt_cito + gt_cito, + gt_ape, + gt_mega } geocache_type; typedef enum { @@ -146,11 +205,11 @@ typedef struct { } utf_string; typedef struct { - geocache_type type; - geocache_container container; int id; /* The decimal cache number */ - int diff; /* (multiplied by ten internally) */ - int terr; /* (likewise) */ + geocache_type type:5; + geocache_container container:4; + unsigned int diff:6; /* (multiplied by ten internally) */ + unsigned int terr:6; /* (likewise) */ time_t exported; time_t last_found; char *placer; /* Placer name */ @@ -173,12 +232,15 @@ typedef struct xml_tag { typedef void (*fs_destroy)(void *); typedef void (*fs_copy)(void **, void *); +typedef void (*fs_convert)(void *); + typedef struct format_specific_data { long type; struct format_specific_data *next; fs_destroy destroy; fs_copy copy; + fs_convert convert; } format_specific_data; format_specific_data *fs_chain_copy( format_specific_data *source ); @@ -197,6 +259,8 @@ fs_xml *fs_xml_alloc( long type ); #define FS_AN1W 0x616e3177L #define FS_AN1L 0x616e316cL #define FS_AN1V 0x616e3176L +#define FS_OZI 0x6f7a6900L +#define FS_GMSD 0x474d5344L /* GMSD = Garmin specific data */ /* * Misc bitfields inside struct waypoint; @@ -204,6 +268,7 @@ fs_xml *fs_xml_alloc( long type ); typedef struct { unsigned int icon_descr_is_dynamic:1; unsigned int shortname_is_synthetic:1; + unsigned int cet_converted:1; /* strings are converted to UTF8; interesting only for input */ } wp_flags; /* @@ -285,7 +350,10 @@ typedef struct { float speed; /* Optional: meters per second. */ fix_type fix; /* Optional: 3d, 2d, etc. */ int sat; /* Optional: number of sats used for fix */ - + + unsigned char heartrate; /* Beats/min. likely to get moved to fs. */ + unsigned char cadence; /* revolutions per minute */ + float temperature; /* Degrees celsius */ geocache_data gc_data; format_specific_data *fs; void *extra_data; /* Extra data added by, say, a filter. */ @@ -296,11 +364,31 @@ typedef struct { queue waypoint_list; /* List of child waypoints */ char *rte_name; char *rte_desc; + char *rte_url; int rte_num; int rte_waypt_ct; /* # waypoints in waypoint list */ format_specific_data *fs; + unsigned short cet_converted; /* strings are converted to UTF8; interesting only for input */ } route_head; +/* + * Structure of recomputed track/roue data. + */ +typedef struct { + double distance_meters; + double max_alt; + double min_alt; + double max_spd; /* Meters/sec */ + double min_spd; /* Meters/sec */ + double avg_hrt; /* Avg Heartrate */ + double avg_cad; /* Avg Cadence */ + time_t start; /* Min time */ + time_t end; /* Max time */ + int min_hrt; /* Min Heartrate */ + int max_hrt; /* Max Heartrate */ + int max_cad; /* Max Cadence */ +} computed_trkdata; + /* * Bounding box information. */ @@ -311,11 +399,17 @@ typedef struct { double min_lon; } bounds; +typedef struct { + int request_terminate; +} posn_status; + typedef void (*ff_init) (char const *); typedef void (*ff_deinit) (void); typedef void (*ff_read) (void); typedef void (*ff_write) (void); typedef void (*ff_exit) (void); +typedef void (*ff_writeposn) (waypoint *); +typedef waypoint * (*ff_readposn) (posn_status *); #ifndef DEBUG_MEM char * get_option(const char *iarglist, const char *argname); @@ -339,6 +433,9 @@ waypoint * waypt_new(void); void waypt_del (waypoint *); void waypt_free (waypoint *); void waypt_disp_all(waypt_cb); +void waypt_init_bounds(bounds *bounds); +int waypt_bounds_valid(bounds *bounds); +void waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp); void waypt_compute_bounds(bounds *); void waypt_flush(queue *); void waypt_flush_all(void); @@ -348,46 +445,68 @@ void free_gpx_extras (xml_tag * tag); void xcsv_setup_internal_style(const char *style_buf); void xcsv_read_internal_style(const char *style_buf); waypoint * find_waypt_by_name(const char *name); +void waypt_backup(signed int *count, queue **head_bak); +void waypt_restore(signed int count, queue *head_bak); route_head *route_head_alloc(void); void route_add (waypoint *); void route_add_wpt(route_head *rte, waypoint *wpt); void route_del_wpt(route_head *rte, waypoint *wpt); +void track_add_wpt(route_head *rte, waypoint *wpt); +void track_del_wpt(route_head *rte, waypoint *wpt); void route_add_head(route_head *rte); void route_del_head(route_head *rte); void route_reverse(const route_head *rte_hd); +waypoint * route_find_waypt_by_name(route_head *rh, const char *name); void track_add_head(route_head *rte); void track_del_head(route_head *rte); +void route_disp(const route_head *rte, waypt_cb); void route_disp_all(route_hdr, route_trl, waypt_cb); void track_disp_all(route_hdr, route_trl, waypt_cb); -void route_free (route_head *); void route_flush( queue *); void route_flush_all(void); +void route_flush_all_routes(void); +void route_flush_all_tracks(void); +route_head * route_find_route_by_name(const char *name); +route_head * route_find_track_by_name(const char *name); unsigned int route_waypt_count(void); unsigned int route_count(void); +unsigned int track_waypt_count(void); unsigned int track_count(void); +void route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ); +void route_backup(signed int *count, queue **head_bak); +void route_restore( queue *head_bak); +void route_append( queue *src ); +void track_backup(signed int *count, queue **head_bak); +void track_restore( queue *head_bak); +void track_append( queue *src ); +void route_flush( queue *head ); +void track_recompute( const route_head *trk, computed_trkdata **); /* * All shortname functions take a shortname handle as the first arg. * This is an opaque pointer. Callers must not fondle the contents of it. */ +typedef struct short_handle * short_handle; #ifndef DEBUG_MEM -char *mkshort (void *, const char *); +char *mkshort (short_handle, const char *); void *mkshort_new_handle(void); #else -char *MKSHORT(void *, const char *, DEBUG_PARAMS); +char *MKSHORT(short_handle, const char *, DEBUG_PARAMS); void *MKSHORT_NEW_HANDLE(DEBUG_PARAMS); #define mkshort( a, b) MKSHORT(a,b,__FILE__, __LINE__) #define mkshort_new_handle() MKSHORT_NEW_HANDLE(__FILE__,__LINE__) #endif -char *mkshort_from_wpt(void *h, const waypoint *wpt); -void mkshort_del_handle(void *h); -void setshort_length(void *, int n); -void setshort_badchars(void *, const char *); -void setshort_goodchars(void *, const char *); -void setshort_mustupper(void *, int n); -void setshort_mustuniq(void *, int n); -void setshort_whitespace_ok(void *, int n); +char *mkshort_from_wpt(short_handle h, const waypoint *wpt); +void mkshort_del_handle(short_handle *h); +void setshort_length(short_handle, int n); +void setshort_badchars(short_handle, const char *); +void setshort_goodchars(short_handle, const char *); +void setshort_mustupper(short_handle, int n); +void setshort_mustuniq(short_handle, int n); +void setshort_whitespace_ok(short_handle, int n); +void setshort_repeating_whitespace_ok(short_handle, int n); +void setshort_defname(short_handle, const char *s); /* * Vmem flags values. @@ -436,18 +555,23 @@ void vmem_realloc(vmem_t*, size_t); #define ARGTYPE_TYPEMASK 0x00000fff #define ARGTYPE_FLAGMASK 0xfffff000 +#define ARG_NOMINMAX NULL, NULL +#define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX} + typedef struct arglist { char *argstring; char **argval; char *helpstring; char *defaultvalue; - long argtype; + gbuint32 argtype; + char *minvalue; /* minimum value for numeric options */ + char *maxvalue; /* maximum value for numeric options */ } arglist_t; typedef enum { ff_type_file = 1, /* normal format: useful to a GUI. */ ff_type_internal, /* fmt not useful with default options */ - ff_type_serial, /* format describes a serial protoco (GUI can display port names) */ + ff_type_serial /* format describes a serial protocol (GUI can display port names) */ } ff_type; typedef enum { @@ -461,12 +585,26 @@ typedef enum { ff_cap_read = 1, ff_cap_write = 2 } ff_cap; + #define FF_CAP_RW_ALL \ { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write } #define FF_CAP_RW_WPT \ { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none} +/* + * Format capabilities for realtime positioning. + */ +typedef struct position_ops { + ff_init rd_init; + ff_readposn rd_position; + ff_deinit rd_deinit; + + ff_init wr_init; + ff_writeposn wr_position; + ff_deinit wr_deinit; +} position_ops_t; + /* * Describe the file format to the caller. */ @@ -481,6 +619,9 @@ typedef struct ff_vecs { ff_write write; ff_exit exit; arglist_t *args; + char *encode; + int fixed_encode; + position_ops_t position_ops; } ff_vecs_t; typedef struct style_vecs { @@ -489,41 +630,25 @@ typedef struct style_vecs { } style_vecs_t; extern style_vecs_t style_list[]; -typedef struct filter_vecs { - filter_init f_init; - filter_process f_process; - filter_deinit f_deinit; - filter_exit f_exit; - arglist_t *args; -} filter_vecs_t; - void waypt_init(void); void route_init(void); void waypt_disp(const waypoint *); void waypt_status_disp(int total_ct, int myct); -void fatal(const char *, ...) -#if __GNUC__ - __attribute__ ((__format__ (__printf__, 1, 2))) - __attribute__((noreturn)) -#endif - ; -void warning(const char *, ...) -#if __GNUC__ - __attribute__ ((__format__ (__printf__, 1, 2))) -#endif - ; + +NORETURN fatal(const char *, ...) PRINTFLIKE(1, 2); +void is_fatal(const int condition, const char *, ...) PRINTFLIKE(2, 3); +void warning(const char *, ...) PRINTFLIKE(1, 2); + ff_vecs_t *find_vec(char * const, char **); +void assign_option(const char *vecname, arglist_t *ap, const char *val); +void disp_vec_options(const char *vecname, arglist_t *ap); void disp_vecs(void); +void disp_vec( const char *vecname ); void exit_vecs(void); void disp_formats(int version); +const char * name_option(long type); void printposn(const double c, int is_lat); -filter_vecs_t * find_filter_vec(char * const, char **); -void free_filter_vec(filter_vecs_t *); -void disp_filters(int version); -void disp_filter_vecs(void); -void exit_filter_vecs(void); - #ifndef DEBUG_MEM void *xcalloc(size_t nmemb, size_t size); void *xmalloc(size_t size); @@ -574,28 +699,48 @@ void xfputs(const char *errtxt, const char *s, FILE *stream); int case_ignore_strcmp(const char *s1, const char *s2); int case_ignore_strncmp(const char *s1, const char *s2, int n); +int str_match(const char *str, const char *match); +int case_ignore_str_match(const char *str, const char *match); char *strsub(const char *s, const char *search, const char *replace); char *gstrsub(const char *s, const char *search, const char *replace); +char *xstrrstr(const char *s1, const char *s2); void rtrim(char *s); +char * lrtrim(char *s); +int xasprintf(char **strp, const char *fmt, ...); +char *strupper(char *src); +char *strlower(char *src); signed int get_tz_offset(void); +time_t mklocaltime(struct tm *t); time_t mkgmtime(struct tm *t); time_t current_time(void); signed int month_lookup(const char *m); const char *get_cache_icon(const waypoint *waypointp); const char *gs_get_cachetype(geocache_type t); +const char *gs_get_container(geocache_container t); char * xml_entitize(const char * str); char * html_entitize(const char * str); char * strip_html(const utf_string*); char * strip_nastyhtml(const char * in); +char * convert_human_date_format(const char *human_datef); /* "MM,YYYY,DD" -> "%m,%Y,%d" */ +char * convert_human_time_format(const char *human_timef); /* "HH+mm+ss" -> "%H+%M+%S" */ +char * pretty_deg_format(double lat, double lon, char fmt, int html); /* decimal -> dd.dddd or dd mm.mmm or dd mm ss */ /* * Character encoding transformations. */ -char * str_utf8_to_cp1252(const char * str); -char * str_utf8_to_ascii(const char * str); -char * str_iso8859_1_to_utf8(const char *str ); +#define CET_NOT_CONVERTABLE_DEFAULT '$' +#define CET_CHARSET_ASCII "US-ASCII" +#define CET_CHARSET_UTF8 "UTF-8" +#define CET_CHARSET_MS_ANSI "MS-ANSI" +#define CET_CHARSET_LATIN1 "ISO-8859-1" + +#define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str)) +#define str_cp1252_to_utf8(str) cet_str_cp1252_to_utf8((str)) + +#define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str)) +#define str_iso8859_1_to_utf8(str) cet_str_iso8859_1_to_utf8((str)) /* this lives in gpx.c */ time_t xml_parse_time( const char *cdatastr ); @@ -632,18 +777,23 @@ typedef struct { * Protypes for Endianness helpers. */ -signed int be_read16(void *p); -signed int be_read32(void *p); -signed int le_read16(void *p); -signed int le_read32(void *p); +signed int be_read16(const void *p); +signed int be_read32(const void *p); +signed int le_read16(const void *p); +signed int le_read32(const void *p); void le_read64(void *dest, const void *src); -void be_write16(void *pp, unsigned i); -void be_write32(void *pp, unsigned i); -void le_write16(void *pp, unsigned i); -void le_write32(void *pp, unsigned i); +void be_write16(void *pp, const unsigned i); +void be_write32(void *pp, const unsigned i); +void le_write16(void *pp, const unsigned i); +void le_write32(void *pp, const unsigned i); double pdb_read_double(void *p); void pdb_write_double(void *pp, double d); +double le_read_double(void *p); +double be_read_double(void *p); +void le_write_double(void *p, double d); +void be_write_double(void *p, double d); + /* * Prototypes for generic conversion routines (util.c). */ @@ -655,11 +805,63 @@ double degrees2ddmm(double deg_val); * From util_crc.c */ unsigned long get_crc32(const void * data, int datalen); +unsigned long get_crc32_s(const void * data); + +/* + * From units.c + */ +typedef enum { + units_unknown = 0, + units_statute = 1, + units_metric =2 +} fmt_units; + +int fmt_setunits(fmt_units); +double fmt_distance(const double, char **tag); +double fmt_speed(const double, char **tag); + +/* + * From gbsleep.c + */ +void gb_sleep(unsigned long microseconds); + +/* + * From nmea.c + */ +int nmea_cksum(const char *const buf); + +/* + * Color helpers. + */ +int color_to_bbggrr(char *cname); /* * A constant for unknown altitude. It's tempting to just use zero * but that's not very nice for the folks near sea level. */ -#define unknown_alt -99999999.0 +#define unknown_alt -99999999.0 +#define unknown_course -999.0 +#define unknown_speed -999.0 +/* + * textfile: buffered OS independent (CRLF,NL,CR) text reader + */ + +typedef struct +{ + FILE *file_in; + char buf[1024]; + char *buf_pos; + char *buf_end; + char *line; + int line_size; + int line_no; + unsigned char tfclose:1; +} textfile_t; + +textfile_t *textfile_init(const FILE *file_in); +textfile_t *textfile_open_read(const char *filename, const char *module); +void textfile_done(textfile_t *tf); +char *textfile_read(textfile_t *tf); +int textfile_getc(textfile_t *tf); #endif /* gpsbabel_defs_h_included */ diff --git a/delgpl.c b/delgpl.c index 3e65936bf..76c88180c 100644 --- a/delgpl.c +++ b/delgpl.c @@ -33,7 +33,7 @@ typedef struct gpl_point { double lon; double alt; /* in feet */ double heading; - double speed; /* mps */ + double speed; /* mph */ unsigned int tm; unsigned int dummy3; } gpl_point_t; @@ -46,8 +46,8 @@ gpl_rd_init(const char *fname) { gplfile_in = xfopen(fname, "rb", MYNAME); if (sizeof(struct gpl_point) != 56) { - fatal(MYNAME ": gpl_point is %d instead of 56.\n", - sizeof(struct gpl_point)); + fatal(MYNAME ": gpl_point is %lu instead of 56.\n", + (unsigned long) sizeof(struct gpl_point)); } } @@ -64,12 +64,17 @@ gpl_read(void) while (fread(&gp, sizeof(gp), 1, gplfile_in) > 0) { wpt_tmp = waypt_new(); - le_read64(&wpt_tmp->latitude, &gp.lat); - le_read64(&wpt_tmp->longitude, &gp.lon); - le_read64(&alt_feet, &gp.alt); - wpt_tmp->altitude = alt_feet * .3048; + wpt_tmp->latitude = le_read_double(&gp.lat); + wpt_tmp->longitude = le_read_double(&gp.lon); + alt_feet = le_read_double(&gp.alt); + wpt_tmp->altitude = FEET_TO_METERS(alt_feet); wpt_tmp->creation_time = le_read32(&gp.tm); - route_add_wpt(track_head, wpt_tmp); + + wpt_tmp->course = le_read_double(&gp.heading); + wpt_tmp->speed = le_read_double(&gp.speed); + wpt_tmp->speed = MILES_TO_METERS(wpt_tmp->speed)/3600; + + track_add_wpt(track_head, wpt_tmp); } } @@ -95,11 +100,19 @@ gpl_wr_deinit(void) static void gpl_trackpt(const waypoint *wpt) { - double alt_feet = wpt->altitude / .3048; - gpl_point_t gp = {0}; - le_read64(&gp.lat, &wpt->latitude); - le_read64(&gp.lon, &wpt->longitude); - le_read64(&gp.alt, &alt_feet); + double alt_feet = METERS_TO_FEET(wpt->altitude); + int status = 3; + gpl_point_t gp; + double speed = 3600*METERS_TO_MILES(wpt->speed); + double heading = wpt->course; + + memset(&gp, 0, sizeof(gp)); + le_write32(&gp.status, status); + le_write_double(&gp.lat, wpt->latitude); + le_write_double(&gp.lon, wpt->longitude); + le_write_double(&gp.alt, alt_feet ); + le_write_double(&gp.speed, speed ); + le_write_double(&gp.heading, heading ); le_write32(&gp.tm, wpt->creation_time); fwrite(&gp, sizeof(gp), 1, gplfile_out); @@ -120,5 +133,7 @@ ff_vecs_t gpl_vecs = { gpl_wr_deinit, gpl_read, gpl_write, - NULL + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */ }; diff --git a/discard.c b/discard.c index 7ecca8152..1b69c8c86 100644 --- a/discard.c +++ b/discard.c @@ -18,11 +18,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -#include -#include "defs.h" -extern queue waypt_head; +#include "defs.h" +#include "filterdefs.h" +#if FILTERS_ENABLED static char *hdopopt = NULL; static char *vdopopt = NULL; static char *andopt = NULL; @@ -32,14 +32,41 @@ static double vdopf; static arglist_t fix_args[] = { {"hdop", &hdopopt, "Suppress waypoints with higher hdop", - "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT}, + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, {"vdop", &vdopopt, "Suppress waypoints with higher vdop", - "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT}, + "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, {"hdopandvdop", &andopt, "Link hdop and vdop supression with AND", - NULL, ARGTYPE_BOOL}, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR }; +/* + * Decide whether to keep or toss this point. + */ +static void +fix_process_wpt(const waypoint *wpt) +{ + int del = 0; + int delh = 0; + int delv = 0; + waypoint *waypointp = (waypoint *) wpt; + + if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) + delh = 1; + if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) + delv = 1; + + if (andopt) + del = delh && delv; + else + del = delh || delv; + + if (del) { + waypt_del(waypointp); + waypt_free(waypointp); + } +} + static void fix_process_track(const route_head *trk) { @@ -47,65 +74,18 @@ fix_process_track(const route_head *trk) queue *elem, *tmp; QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - - int del = 0; - int delh = 0; - int delv = 0; - waypointp = (waypoint *)elem; - - if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) - delh = 1; - if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) - delv = 1; - - if (andopt) - del = delh && delv; - else - del = delh || delv; - - if (del) { - waypt_del(waypointp); - waypt_free(waypointp); - } + fix_process_wpt(waypointp); } } -void +static void fix_process(void) { - waypoint * waypointp; - queue *elem, *tmp; - extern queue waypt_head; - - // Filter waypoints - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - - int del = 0; - int delh = 0; - int delv = 0; + // Filter waypoints. + waypt_disp_all(fix_process_wpt); - waypointp = (waypoint *)elem; - - if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) - delh = 1; - if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) - delv = 1; - - if (andopt) - del = delh && delv; - else - del = delh || delv; - - if (del) { - waypt_del(waypointp); - waypt_free(waypointp); - } - - } - // Filter tracks track_disp_all(fix_process_track, NULL, NULL); @@ -114,28 +94,25 @@ fix_process(void) } -void +static void fix_init(const char *args) { if (hdopopt) hdopf = atof(hdopopt); else hdopf = -1.0; + if (vdopopt) vdopf = atof(vdopopt); else vdopf = -1.0; } -void -fix_deinit(void) -{ -} - filter_vecs_t discard_vecs = { fix_init, fix_process, - fix_deinit, + NULL, NULL, fix_args }; +#endif diff --git a/dmtlog.c b/dmtlog.c new file mode 100644 index 000000000..05d70b055 --- /dev/null +++ b/dmtlog.c @@ -0,0 +1,719 @@ +/* + + Support for TrackLogs digital mapping (.trl) files, + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include "xmlgeneric.h" + +#include +#include +#include + +#define MYNAME "dmtlog" + +#define DEFLATE_BUFF_SIZE 16384 + +static gbfile *fin, *fout; + +static char *xmlbin; +static waypoint *xmlwpt; +static route_head *xmltrk; +static char *xmlgrid; +static int xmldatum, datum_WGS84, datum_OSGB36; +static double xmlEasting, xmlNorthing; +static double xmlLatitude, xmlLongitude; +static double xmlAltitude; + +#if !ZLIB_INHIBITED +static int xmlbinsize; +#endif + +static char header_written; +static char *opt_index; +static int track_index, this_index; + +static +arglist_t dmtlog_args[] = { + { "index", &opt_index, + "Index of track (if more the one in source)", "1", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +#if !ZLIB_INHIBITED +static xg_callback tlog3a_xgcb_version, tlog3a_xgcb_length, tlog3a_xgcb_data; + +static xg_tag_mapping tlog3a_xgcb_map[] = { + { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" }, + { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" }, + { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" }, + { NULL, 0, NULL} +}; +#endif + +static xg_callback tlog3b_xgcb_tfna, tlog3b_xgcb_tfdes; +static xg_callback tlog3b_xgcb_wptst, tlog3b_xgcb_tptst; +static xg_callback tlog3b_xgcb_tpten, tlog3b_xgcb_wpten; +static xg_callback tlog3b_xgcb_wptid, tlog3b_xgcb_wptdt; +static xg_callback tlog3b_xgcb_wptgr, tlog3b_xgcb_wptea; +static xg_callback tlog3b_xgcb_wptno, tlog3b_xgcb_wptal; +static xg_callback tlog3b_xgcb_tptdt; + +static xg_tag_mapping tlog3b_xgcb_map[] = { + { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" }, + { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" }, + { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" }, + { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" }, + { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" }, + { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" }, + { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" }, + { NULL, 0, NULL} +}; + +/* helpers */ + +static void +convert_datum(waypoint *wpt, int datum) +{ + if (datum != datum_WGS84) { + double lat = wpt->latitude; + double lon = wpt->longitude; + double alt = wpt->altitude; + GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt, + &wpt->latitude, &wpt->longitude, &wpt->altitude, + datum); + } +} + + +static void +finalize_pt(waypoint *wpt) +{ + if (strcmp(xmlgrid, "BNG") == 0) { + GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing, + &wpt->latitude, &wpt->longitude); + xmldatum = datum_OSGB36; + } + else { + wpt->latitude = xmlLatitude; + wpt->longitude = xmlLongitude; + } + wpt->altitude = xmlAltitude; + convert_datum(wpt, xmldatum); +} + +/* xml-reader callbacks */ + +#if !ZLIB_INHIBITED +static void +tlog3a_xgcb_version(const char *args, const char **unused) +{ + if (strcmp(args, "1") != 0) + fatal(MYNAME ": Unsupported file version '%s'!\n", args); +} + +static void +tlog3a_xgcb_length(const char *args, const char **unused) +{ +} + +static void +tlog3a_xgcb_data(const char *args, const char **unused) +{ + int len; + char *bin; + char *cin, *cout; + char cl, ch; + + len = strlen(args); + bin = xmalloc((len >> 1) + 1); + + cin = (char *)args; + cout = bin; + + cl = 0x10; + while (*cin) { + char c = *cin++; + + if (c == '\0') break; + else if ((c >= 'A') && (c <= 'F')) c -= 'A' - 10; + else if ((c >= 'a') && (c <= 'f')) c -= 'a' - 10; + else if ((c >= '0') && (c <= '9')) c -= '0'; + else continue; + + if (cl == 0x10) cl = c; + else { + ch = (cl << 4) | c; + *cout++ = ch; + cl = 0x10; + } + } + xmlbin = bin; + xmlbinsize = (cout - bin); +} +#endif + + +static void +tlog3b_xgcb_tfna(const char *args, const char **unused) +{ + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_name = strdup(args); +} + + +static void +tlog3b_xgcb_tfdes(const char *args, const char **unused) +{ + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_desc = strdup(args); +} + + +static void +tlog3b_xgcb_wptst(const char *args, const char **unused) +{ + xmlwpt = waypt_new(); + xmldatum = datum_WGS84; +} + + +static void +tlog3b_xgcb_tptst(const char *args, const char **unused) +{ + xmlwpt = waypt_new(); + xmldatum = datum_WGS84; +} + + +static void +tlog3b_xgcb_tpten(const char *args, const char **unused) +{ + finalize_pt(xmlwpt); + + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + track_add_wpt(xmltrk, xmlwpt); + xmlwpt = NULL; +} + + +static void +tlog3b_xgcb_wptid(const char *args, const char **unused) +{ + if (*args) + xmlwpt->shortname = xstrdup(args); +} + + +static void +tlog3b_xgcb_wptdt(const char *args, const char **unused) +{ + xmldatum = GPS_Lookup_Datum_Index(args); +} + + +static void +tlog3b_xgcb_wptgr(const char *args, const char **unused) +{ + if (xmlgrid != NULL) { + if (strcmp(xmlgrid, args) == 0) return; + xfree(xmlgrid); + } + xmlgrid = xstrdup(args); +} + + +static void +tlog3b_xgcb_wptno(const char *args, const char **unused) +{ + xmlNorthing = atof(args); +} + + +static void +tlog3b_xgcb_wptea(const char *args, const char **unused) +{ + xmlEasting = atof(args); +} + + +static void +tlog3b_xgcb_wptal(const char *args, const char **unused) +{ + xmlAltitude = atof(args); +} + + +static void +tlog3b_xgcb_tptdt(const char *args, const char **unused) +{ + xmldatum = GPS_Lookup_Datum_Index(args); +} + + +static void +tlog3b_xgcb_wpten(const char *args, const char **unused) +{ + finalize_pt(xmlwpt); + waypt_add(xmlwpt); + xmlwpt = NULL; +} + + +static int +read_datum(gbfile *f) +{ + int res; + char *d, *g; + + d = gbfgetpstr(f); + g = gbfgetpstr(f); + + res = GPS_Lookup_Datum_Index(d); + + if (*g && (strcmp(d, g) != 0)) { + fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n", + d, g); + } + xfree(d); + xfree(g); + + return res; +} + + +static void +read_CTrackFile(const int version) +{ + char buf[128]; + gbuint32 ver; + gbint32 tcount, wcount; + gbint16 u1; + gbint32 ux; + route_head *track; + int i; + int datum; + + u1 = gbfgetint16(fin); + + gbfread(buf, 1, 10, fin); + if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0)) + fatal(MYNAME ": Unknown or invalid track file.\n"); + + if (version == 8) { + for (i = 1; i <= 9; i++) + gbfread(buf, 1, 4, fin); + } + ver = gbfgetint32(fin); + if (ver != version) + fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver); + + ux = gbfgetint32(fin); // Unknown 2 + ux = gbfgetint32(fin); // Unknown 3 + ux = gbfgetint32(fin); // Unknown 4 + + track = route_head_alloc(); + track_add_head(track); + + /* S1 .. S9: comments, hints, jokes, aso */ + for (i = 0; i < 9; i++) { + int c = gbfgetc(fin); + gbfseek(fin, c, SEEK_CUR); + } + + tcount = gbfgetint32(fin); + if (tcount > 0) { + datum = read_datum(fin); + if (version == 8) { + int len; + + gbfread(buf, 1, 4, fin); + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); + } + } + + while (tcount > 0) + { + waypoint *wpt; + + tcount--; + + if (version == 8) + datum = read_datum(fin); + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + track_add_wpt(track, wpt); + + if (version == 8) + gbfseek(fin, 34, SEEK_CUR); + } + + wcount = gbfgetint32(fin); + + if (wcount == 0) return; + + if (version == 8) { + warning(MYNAME ": We don't yet support waypoints for this file version!\n"); + return; + } + + datum = read_datum(fin); + + while (wcount > 0) { + waypoint *wpt; + gbint32 namect, i; + + wcount--; + + if (version == 8) + datum = read_datum(fin); + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + namect = gbfgetint32(fin); + + // variants of shortname + + for (i = 0; i < namect; i++) { + char *name = gbfgetpstr(fin); + if (name && *name) { + switch(i) { + case 0: wpt->description = xstrdup(name); break; + case 1: wpt->shortname = xstrdup(name); break; + } + } + xfree(name); + } + if (version == 8) + gbfseek(fin, 34, SEEK_CUR); + + waypt_add(wpt); + } +} + + +#if !ZLIB_INHIBITED + +static int +inflate_buff(const char *buff, const size_t size, char **out_buff) +{ + int res = Z_OK; + z_stream strm; + char out[DEFLATE_BUFF_SIZE]; + char *cout = NULL; + gbuint32 bytes = 0; + gbuint32 have; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + res = inflateInit(&strm); + if (res != Z_OK) { + return res; + } + + strm.avail_in = size; + strm.next_in = (void *)buff; + + do { + strm.avail_out = DEFLATE_BUFF_SIZE; + strm.next_out = (void *)out; + res = inflate(&strm, Z_NO_FLUSH); + + switch (res) { + case Z_NEED_DICT: + res = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return res; + } + have = DEFLATE_BUFF_SIZE - strm.avail_out; + if (have > 0) { + cout = xrealloc(cout, bytes + have); + memcpy(cout+bytes, out, have); + bytes+=have; + } + } while (strm.avail_out == 0); + + *out_buff = cout; + return res; +} + + +static void +read_CXMLSafe(void) +{ + char *xmlstr = NULL; + + xmlbin = NULL; + xmlbinsize = 0; + + xml_init(fin->name, tlog3a_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + if (xmlbin != NULL) { + inflate_buff(xmlbin, xmlbinsize, &xmlstr); + xfree(xmlbin); + + xml_init(NULL, tlog3b_xgcb_map, NULL); + xml_readstring(xmlstr); + xml_deinit(); + + xfree(xmlstr); + } +} + +#endif + +static void +read_XML(void) +{ + xml_init(fin->name, tlog3b_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + return; +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +dmtlog_rd_init(const char *fname) +{ + fin = gbfopen_le(fname, "rb", MYNAME); + + datum_OSGB36 = GPS_Lookup_Datum_Index("OSGB36"); + datum_WGS84 = GPS_Lookup_Datum_Index("WGS84"); + + xmlbin = NULL; + xmltrk = NULL; + xmlwpt = NULL; + xmlgrid = NULL; +} + +static void +dmtlog_rd_deinit(void) +{ + gbfclose(fin); + if (xmlgrid != NULL) xfree(xmlgrid); +} + +static void +dmtlog_read(void) +{ + switch(gbfgetuint32(fin)) { + + case 0x4FFFF: + read_CTrackFile(4); + break; + + case 0x8FFFF: + read_CTrackFile(8); + break; + + case 0x4d58433c: +#if !ZLIB_INHIBITED + read_CXMLSafe(); +#else + fatal(MYNAME ": Zlib was not included in this build.\n"); +#endif + break; + case 0x7254433c: + read_XML(); + break; + + default: + fatal(MYNAME ": Unknown or unsupported file type.\n"); + } +} + +static void +dmtlog_wr_init(const char *fname) +{ + fout = gbfopen_le(fname, "wb", MYNAME); +} + +static void +dmtlog_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +write_header(const route_head *trk) +{ + int count, i; + char *cout; + const char ZERO = '\0'; + + header_written = 1; + + count = 0; + if (trk != NULL) { + queue *curr, *prev; + QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++; + } + gbfputpstr(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout); + + xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count()); + gbfputpstr(cout, fout); + xfree(cout); + + for (i = 3; i <= 8; i++) gbfputc(ZERO, fout); + gbfputpstr("GPSBabel", fout); + gbfputint32(count, fout); + if (count > 0) { + gbfputpstr("WGS84", fout); + gbfputpstr("WGS84", fout); + } +} + +static void +track_hdr_cb(const route_head *trk) +{ + + this_index++; + if (this_index != track_index) return; + write_header(trk); +} + +static void +track_tlr_cb(const route_head *trk) +{ +} + +static void +track_wpt_cb(const waypoint *wpt) +{ + if (this_index != track_index) return; + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude, fout); +} + +static void +wpt_cb(const waypoint *wpt) +{ + int names; + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude, fout); + + names = 1; + if (wpt->description && *wpt->description) names = 2; + gbfputint32(names, fout); + if (names > 1) gbfputpstr(wpt->description, fout); + gbfputpstr(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout); +} + +static void +dmtlog_write(void) +{ + track_index = atoi(opt_index); + /* ... validate index */ + + gbfputint32(0x4FFFF, fout); + gbfputuint16(0x0A, fout); + gbfputs("CTrackFile", fout); + gbfputint32(4, fout); + gbfputint32(1, fout); + gbfputint32(0x100001, fout); + gbfputuint32((const gbuint32)gpsbabel_now, fout); + + header_written = 0; + this_index = 0; + track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb); + if (!header_written) + write_header(NULL); + gbfputint32(waypt_count(), fout); + if (waypt_count() > 0) { + gbfputpstr("WGS84", fout); + gbfputpstr("WGS84", fout); + waypt_disp_all(wpt_cb); + } +} + +/**************************************************************************/ + +ff_vecs_t dmtlog_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + dmtlog_rd_init, + dmtlog_wr_init, + dmtlog_rd_deinit, + dmtlog_wr_deinit, + dmtlog_read, + dmtlog_write, + NULL, + dmtlog_args, + CET_CHARSET_ASCII, 0 + +}; + +/**************************************************************************/ diff --git a/duplicate.c b/duplicate.c index 5556be28e..f40e1bf5f 100644 --- a/duplicate.c +++ b/duplicate.c @@ -20,9 +20,9 @@ */ #include #include "defs.h" +#include "filterdefs.h" -extern queue waypt_head; - +#if FILTERS_ENABLED static char *snopt = NULL; static char *lcopt = NULL; static char *purge_duplicates = NULL; @@ -31,14 +31,14 @@ static char *correct_coords = NULL; static arglist_t dup_args[] = { {"shortname", &snopt, "Suppress duplicate waypoints based on name", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL}, + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, {"location", &lcopt, "Suppress duplicate waypoint based on coords", - NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL}, + NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, {"all", &purge_duplicates, "Suppress all instances of duplicates", - NULL, ARGTYPE_BOOL}, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, {"correct", &correct_coords, "Use coords from duplicate points", - NULL, ARGTYPE_BOOL}, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR }; @@ -159,7 +159,8 @@ compare(const void *a, const void *b) } -void + +static void duplicate_process(void) { waypoint * waypointp; @@ -172,7 +173,6 @@ duplicate_process(void) int i, ct = waypt_count(); wpt_ptr *htable, *bh; queue *elem, *tmp; - extern queue waypt_head; htable = (wpt_ptr *) xmalloc(ct * sizeof(*htable)); bh = htable; @@ -250,20 +250,11 @@ duplicate_process(void) } } -void -duplicate_init(const char *args) -{ -} - -void -duplicate_deinit(void) -{ -} - filter_vecs_t duplicate_vecs = { - duplicate_init, + NULL, duplicate_process, - duplicate_deinit, + NULL, NULL, dup_args }; +#endif diff --git a/easygps.c b/easygps.c index 7d804e3c7..b203ada69 100644 --- a/easygps.c +++ b/easygps.c @@ -24,7 +24,7 @@ static FILE *file_in; static FILE *file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; /* static char *deficon = NULL; */ #define MYNAME "EasyGPS" @@ -33,7 +33,7 @@ static arglist_t easygps_args[] = { /* {"deficon", &deficon, "Default icon name", "Waypoint", ARGTYPE_STRING}, */ - {0, 0, 0, 0 } + ARG_TERMINATOR }; static void @@ -69,7 +69,7 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } /* @@ -77,7 +77,7 @@ wr_deinit(void) * storage. */ static void * -pread(void) +pas_read(void) { char *d; int ilen; @@ -96,7 +96,6 @@ data_read(void) char ibuf[10]; char bbuf[4096]; char *bbufp; - double d; do { unsigned char tag; waypoint *wpt_tmp; @@ -106,20 +105,20 @@ data_read(void) for (tag = fgetc(file_in); tag != 0xff; tag = fgetc(file_in)) { switch (tag) { case 1: - wpt_tmp->shortname = (char *) pread(); + wpt_tmp->shortname = (char *) pas_read(); break; case 2: case 3: - wpt_tmp->description = (char *) pread(); + wpt_tmp->description = (char *) pas_read(); break; case 5: - wpt_tmp->notes = (char *) pread(); + wpt_tmp->notes = (char *) pas_read(); break; case 6: - wpt_tmp->url_link_text = (char *) pread(); + wpt_tmp->url_link_text = (char *) pas_read(); break; case 7: - wpt_tmp->icon_descr = (char *) pread(); + wpt_tmp->icon_descr = (char *) pas_read(); wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; break; case 8: /* NULL Terminated (vs. pascal) descr */ @@ -157,13 +156,11 @@ data_read(void) break; case 0x63: fread(ibuf, 8, 1, file_in); - le_read64(&d, ibuf); - wpt_tmp->latitude = d; + wpt_tmp->latitude = le_read_double(ibuf); break; case 0x64: fread(ibuf, 8, 1, file_in); - le_read64(&d, ibuf); - wpt_tmp->longitude = d; + wpt_tmp->longitude = le_read_double(ibuf); break; case 0x65: case 0x66: @@ -220,10 +217,10 @@ ez_disp(const waypoint *wpt) write_pstring(wpt->icon_descr); } fputc(0x63, file_out); - le_read64(tbuf, &wpt->latitude); + le_write_double(tbuf, wpt->latitude); fwrite(tbuf, 8, 1, file_out); fputc(0x64, file_out); - le_read64(tbuf, &wpt->longitude); + le_write_double(tbuf, wpt->longitude); fwrite(tbuf, 8, 1, file_out); if (wpt->notes) { fputc(5, file_out); @@ -272,5 +269,6 @@ ff_vecs_t easygps_vecs = { data_read, data_write, NULL, - easygps_args + easygps_args, + CET_CHARSET_ASCII, 0 /* CET REVIEW */ }; diff --git a/fatal.c b/fatal.c new file mode 100644 index 000000000..30275f474 --- /dev/null +++ b/fatal.c @@ -0,0 +1,41 @@ +/* + Functions to indicate inconsistent or fatal conditions. + + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +void +fatal(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +void +warning(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + diff --git a/filter_skeleton.c b/filter_skeleton.c index abff8df11..8c5651af7 100644 --- a/filter_skeleton.c +++ b/filter_skeleton.c @@ -2,7 +2,7 @@ Filter skeleton: - Simple copy this file to .c and + Simply copy this file to .c and rename all filter_skeleton tokens to . Replace the stupid name and address in the Copyright few lines below. To active your new filter you have to create a new section in @@ -27,18 +27,20 @@ */ #include "defs.h" +#include "filterdefs.h" #include #define MYNAME "filter_skeleton" +#if FILTERS_ENABLED // Any arg in this list will appear in command line help and will be // populated for you. static arglist_t filter_skeleton_args[] = { // {"foo", &fooopt, "The text of the foo option in help", -// "default", ARGYTPE_STRING} , - {0, 0, 0, 0, 0} +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -46,8 +48,14 @@ arglist_t filter_skeleton_args[] = { *******************************************************************************/ static void -filter_skeleton_init(const char *args) /* optional */ +filter_skeleton_init(const char *args) { + /* Called before filter processing */ + + /* optional. If not needed, delete and replace entry in vecs with NULL */ + + /* This may be used to parse filter options, allocate memory, and do other + * housekeeping that should be done before filtering */ } static void @@ -60,8 +68,29 @@ filter_skeleton_process(void) /* this procedure must be present in vecs */ } static void -filter_skeleton_deinit(void) /* optional */ +filter_skeleton_deinit(void) { + /* called after filter processing */ + + /* optional. If not needed, delete and replace entry in vecs with NULL */ + + /* This should be used to clean up any memory allocations that are no longer + * needed after the filter terminates. */ +} + +static void +filter_skeleton_exit(void) +{ + /* called on program exit */ + + /* optional. If not needed, delete and replace entry in vecs with NULL */ + + /* You should not need this for simple filters, but it may be used to + * clean up memory allocations that must persist from one invocation of + * your filter to the next (for example, the stack in the stack filter.) + * Note that this member will be called even if your filter has not been + * used, so it *cannot* assume that _init or _process has been called + * previously. */ } /*******************************************************************************/ @@ -70,8 +99,9 @@ filter_vecs_t filter_skeleton_vecs = { filter_skeleton_init, filter_skeleton_process, filter_skeleton_deinit, - NULL, + filter_skeleton_exit, filter_skeleton_args }; /*******************************************************************************/ +#endif // FILTERS_ENABLED diff --git a/filter_vecs.c b/filter_vecs.c index 1aa5ca1b4..8dee6d560 100644 --- a/filter_vecs.c +++ b/filter_vecs.c @@ -1,7 +1,7 @@ /* Describe vectors containing filter operations. - Copyright (C) 2002,2004,2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002,2004,2005,2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,8 +19,9 @@ */ -#include #include "defs.h" +#include "filterdefs.h" +#include "inifile.h" typedef struct { filter_vecs_t *vec; @@ -39,44 +40,58 @@ extern filter_vecs_t sort_vecs; extern filter_vecs_t stackfilt_vecs; extern filter_vecs_t trackfilter_vecs; extern filter_vecs_t discard_vecs; +extern filter_vecs_t nuke_vecs; +extern filter_vecs_t interpolatefilt_vecs; +extern filter_vecs_t transform_vecs; static fl_vecs_t filter_vec_list[] = { +#if FILTERS_ENABLED + { + &arcdist_vecs, + "arc", + "Include Only Points Within Distance of Arc", + }, { - &position_vecs, - "position", - "Remove Points Within Distance", - }, - { - &radius_vecs, - "radius", - "Include Only Points Within Radius", - }, + &discard_vecs, + "discard", + "Remove unreliable points with high hdop or vdop" + }, { &duplicate_vecs, "duplicate", "Remove Duplicates", }, - { - &arcdist_vecs, - "arc", - "Include Only Points Within Distance of Arc", + { + &interpolatefilt_vecs, + "interpolate", + "Interpolate between trackpoints" + }, + { + &nuke_vecs, + "nuketypes", + "Remove all waypoints, tracks, or routes" }, { &polygon_vecs, "polygon", "Include Only Points Inside Polygon", }, + { + &position_vecs, + "position", + "Remove Points Within Distance", + }, + { + &radius_vecs, + "radius", + "Include Only Points Within Radius", + }, { &routesimple_vecs, "simplify", "Simplify routes", }, - { - &reverse_route_vecs, - "reverse", - "Reverse stops within routes", - }, { &sort_vecs, "sort", @@ -87,16 +102,22 @@ fl_vecs_t filter_vec_list[] = { "stack", "Save and restore waypoint lists" }, + { + &reverse_route_vecs, + "reverse", + "Reverse stops within routes", + }, { &trackfilter_vecs, "track", "Manipulate track lists" }, { - &discard_vecs, - "discard", - "Remove unreliable points with high hdop or vdop" + &transform_vecs, + "transform", + "Transformate waypoints into a route, tracks into routes, ..." }, +#endif { NULL, NULL, @@ -110,51 +131,54 @@ find_filter_vec(char *const vecname, char **opts) fl_vecs_t *vec = filter_vec_list; char *v = xstrdup(vecname); char *svecname = strtok(v, ","); + int found = 0; while (vec->vec) { arglist_t *ap; char *res; - if (strcmp(svecname, vec->name)) { + if (case_ignore_strcmp(svecname, vec->name)) { vec++; continue; } + /* step 1: initialize by inifile or default values */ + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + char *temp; + + temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (temp == NULL) temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); + if (temp == NULL) temp = ap->defaultvalue; + assign_option(vec->name, ap, temp); + } + } + + /* step 2: override settings with command-line values */ res = strchr(vecname, ','); if (res) { *opts = res+1; if (vec->vec->args) { for (ap = vec->vec->args; ap->argstring; ap++){ - char *opt = get_option(*opts, - ap->argstring); - if ( opts ) { - *ap->argval = opt; - } - else if ( ap->defaultvalue ) { - *ap->argval = xstrdup( - ap->defaultvalue); - } - else { - *ap->argval = NULL; - } - } - } - } else { - *opts = NULL; - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++){ - if ( ap->defaultvalue ) { - *ap->argval = xstrdup( - ap->defaultvalue); - } - else { - *ap->argval = NULL; + char *opt; + + opt = get_option(*opts, ap->argstring); + if ( opt ) { + found = 1; + assign_option(vec->name, ap, opt); + xfree(opt); } } } } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + if (global_opts.debug_level >= 1) + disp_vec_options(vec->name, vec->vec->args); + xfree(v); return vec->vec; @@ -170,7 +194,10 @@ free_filter_vec( filter_vecs_t *fvec ) if ( fvec->args ) { for ( ap = fvec->args; ap->argstring; ap++) { - if (ap->argval && *ap->argval) xfree(*ap->argval); + if (ap->argval && *ap->argval) { + xfree(*ap->argval); + *ap->argval = NULL; + } } } } @@ -210,6 +237,27 @@ disp_filter_vecs(void) } } +void +disp_filter_vec( const char *vecname ) +{ + fl_vecs_t *vec; + arglist_t *ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + if ( case_ignore_strcmp( vec->name, vecname )) { + continue; + } + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN )) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } +} + static signed int alpha (const void *a, const void *b) { @@ -219,6 +267,24 @@ alpha (const void *a, const void *b) return case_ignore_strcmp(ap->desc , bp->desc); } +static void +disp_v1(const fl_vecs_t *vec) +{ + arglist_t *ap; + + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + } +} + /* * Display the available formats in a format that's easy to machine * parse. Typically invoked by programs like graphical wrappers to @@ -237,8 +303,11 @@ disp_filters(int version) switch(version) { case 0: + case 1: for (vec = filter_vec_list; vec->vec; vec++) { printf("%s\t%s\n", vec->name, vec->desc); + if (version > 0) + disp_v1(vec); } break; default: diff --git a/filterdefs.h b/filterdefs.h new file mode 100644 index 000000000..570450000 --- /dev/null +++ b/filterdefs.h @@ -0,0 +1,46 @@ +/* + Filter definitions. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + + +/* + * Filters can do some things that modules really shouldn't do. + * This is our (weak) attempt to make that distinction. + */ + +extern queue waypt_head; + +typedef struct filter_vecs { + filter_init f_init; + filter_process f_process; + filter_deinit f_deinit; + filter_exit f_exit; + arglist_t *args; +} filter_vecs_t; + +filter_vecs_t * find_filter_vec(char * const, char **); +void free_filter_vec(filter_vecs_t *); +void disp_filters(int version); +void disp_filter( const char *vecname ); +void disp_filter_vec( const char *vecname ); +void disp_filter_vecs(void); +void exit_filter_vecs(void); + diff --git a/format_skeleton.c b/format_skeleton.c new file mode 100644 index 000000000..82285d916 --- /dev/null +++ b/format_skeleton.c @@ -0,0 +1,156 @@ +/* + + Format converter module skeleton. + + Steps to create a new format. + + 1) Copy this file to .c + 2) Rename all format_skeleton tokens to . + 3) Replace the fictional name and address in the Copyright section below. + As your work is likely built on the work of others, please retain + the original line. + 4) Create a new section in vecs.c. + 5) Add compilation instructions to Makefile. + 6) Add sample files (it's better when they're created by the "real" + application and not our own output) to reference/ along with + files in a well supported (preferably non-binary) format and + entries in our 'testo' program. This allows users of different + OSes and hardware to exercise your module. + + Copyright (C) YYYY John Doe, anybody@wherever.com + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include + +#define MYNAME "format_skeleton" + + +// Any arg in this list will appear in command line help and will be +// populated for you. +// Values for ARGTYPE_xxx can be found in defs.h and are used to +// select the type of option. +static +arglist_t format_skeleton_args[] = { +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR +}; + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +format_skeleton_rd_init(const char *fname) +{ +// fin = gbfopen(fname, "r", MYNAME); +} + +static void +format_skeleton_rd_deinit(void) +{ +// gbfclose(fin); +} + +static void +format_skeleton_read(void) +{ +// your special code to extract waypoint, route and track +// information from gbfile "fin" +// +// Sample text-file read code: +// char *s; +// while ((s = gbfgetstr(fin))) { +// do_anything(s); +// } +// +// +// For waypoints: +// while (have waypoints) { +// waypoint = waypt_new() +// populate waypoint +// waypt_add(waypoint); +// } +// +// For routes: +// +// route = route_head_alloc(); +// populate struct route_hdr +// route_add_head(route); +// while (have more routepoints) { +// waypoint = waypt_new() +// populate waypoint +// route_add_wpt(route, waypoint) +// } +// +// Tracks are just like routes, except the word "track" replaces "routes". +// +} + +static void +format_skeleton_wr_init(const char *fname) +{ +// fout = gbfopen(fname, "w", MYNAME); +} + +static void +format_skeleton_wr_deinit(void) +{ +// gbfclose(fout); +} + +static void +format_skeleton_write(void) +{ +// Here is how you register callbacks for all waypoints, routes, tracks. +// waypt_disp_all(waypt) +// route_disp_all(head, tail, rtept); +// track_disp_all(head, tail, trkpt); +} + +static void +format_skeleton_exit(void) /* optional */ +{ +} + +/**************************************************************************/ + +// capabilities below means: we can only read and write waypoints +// please change this depending on your new module + +ff_vecs_t format_skeleton_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + format_skeleton_rd_init, + format_skeleton_wr_init, + format_skeleton_rd_deinit, + format_skeleton_wr_deinit, + format_skeleton_read, + format_skeleton_write, + format_skeleton_exit, + format_skeleton_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ +}; +/**************************************************************************/ diff --git a/formspec.c b/formspec.c index 1c20c53c9..ce1dbf90b 100644 --- a/formspec.c +++ b/formspec.c @@ -31,6 +31,8 @@ format_specific_data *fs_chain_copy( format_specific_data *source ) { format_specific_data **copy = &result; while ( source ) { source->copy( (void **)copy, (void *)source ); + /* prevent segfaults from badly-behaved copy functions */ + (*copy)->next = NULL; copy = &((*copy)->next); source = source->next; } diff --git a/garmin.c b/garmin.c index 935266c29..c696357b0 100644 --- a/garmin.c +++ b/garmin.c @@ -1,7 +1,7 @@ /* Jeeps wrapper for Garmin serial protocol. - Copyright (C) 2002, 2003, 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002, 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,10 +24,13 @@ #include "defs.h" #include "jeeps/gps.h" #include "garmin_tables.h" +#include "garmin_fs.h" + +#define SOON 1 #define MYNAME "GARMIN" static const char *portname; -static void *mkshort_handle; +static short_handle mkshort_handle; static GPS_PWay *tx_routelist; static GPS_PWay *cur_tx_routelist_entry; static GPS_PTrack *tx_tracklist; @@ -37,21 +40,25 @@ static char *poweroff = NULL; static char *snlen = NULL; static char *snwhiteopt = NULL; static char *deficon = NULL; +static char *category = NULL; + /* Technically, even this is a little loose as spaces arent allowed */ static char valid_waypt_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; static arglist_t garmin_args[] = { { "snlen", &snlen, "Length of generated shortnames", NULL, - ARGTYPE_INT }, - { "snwhite", &snwhiteopt, "(0/1) Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL}, - { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING }, + ARGTYPE_INT, "1", NULL }, + { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, { "get_posn", &getposn, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL}, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, { "power_off", &poweroff, "Command unit to power itself down", - NULL, ARGTYPE_BOOL}, - { 0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { "category", &category, "Category number to use for written waypoints", + NULL, ARGTYPE_INT, "1", "16"}, + ARG_TERMINATOR }; static const char * d103_symbol_from_icon_number(unsigned int n); @@ -60,7 +67,9 @@ static int d103_icon_number_from_symbol(const char *s); static void rw_init(const char *fname) { - int short_length; + int receiver_short_length; + int receiver_must_upper = 1; + char * receiver_charset = NULL; if (!mkshort_handle) mkshort_handle = mkshort_new_handle(); @@ -92,10 +101,15 @@ rw_init(const char *fname) * Fortunately, getting this "wrong" only results in ugly names * when we're using the synthesize_shortname path. */ - short_length = 10; + receiver_short_length = 10; switch ( gps_waypt_type ) /* waypoint type as defined by jeeps */ { + case 0: + fatal("Garmin unit %d does not support waypoint xfer.", + gps_save_id); + + break; case 100: /* The GARMIN GPS Interface Specification, */ case 101: /* says these waypoint types use an ident */ case 102: /* length of 6. Waypoint types 106, 108 */ @@ -108,19 +122,40 @@ rw_init(const char *fname) case 152: case 154: case 155: - short_length = 6; + receiver_short_length = 6; break; case 106: /* Waypoint types with variable ident length */ case 108: /* Need GPSr id to know the actual length */ case 109: + case 110: switch ( gps_save_id ) { case 130: /* Garmin Etrex (yellow) */ - short_length = 6; + receiver_short_length = 6; break; case 155: /* Garmin V */ - short_length = 20; + case 404: /* SP2720 */ + receiver_short_length = 20; break; + case 382: /* C320 */ + receiver_short_length = 30; + receiver_must_upper = 0; + break; + case 292: /* (60|76)C[s]X series */ + case 421: /* Vista|Legend CX */ + receiver_short_length = 14; + snwhiteopt = xstrdup("1"); + receiver_must_upper = 0; + /* This might be 8859-1 */ + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 231: /* Quest */ + case 463: /* Quest 2 */ + receiver_must_upper = 0; + receiver_short_length = 30; + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 260: /* GPSMap 296 */ default: break; } @@ -132,7 +167,12 @@ rw_init(const char *fname) if (global_opts.debug_level > 0) { fprintf(stderr, "Waypoint type: %d\n" "Chosen waypoint length %d\n", - gps_waypt_type, short_length); + gps_waypt_type, receiver_short_length); + if (gps_category_type) { + fprintf(stderr, "Waypoint category type: %d\n", + gps_category_type); + } + } /* * If the user provided a short_length, override the calculated value. @@ -140,22 +180,32 @@ rw_init(const char *fname) if (snlen) setshort_length(mkshort_handle, atoi(snlen)); else - setshort_length(mkshort_handle, short_length); + setshort_length(mkshort_handle, receiver_short_length); if (snwhiteopt) setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); - setshort_goodchars(mkshort_handle, valid_waypt_chars); - setshort_mustupper(mkshort_handle, 1); + /* + * Until Garmins documents how to determine valid character space + * for the new models, we just release this safety check manually. + */ + if (receiver_must_upper) { + setshort_goodchars(mkshort_handle, valid_waypt_chars); + } else { + setshort_badchars(mkshort_handle, ""); + } + + setshort_mustupper(mkshort_handle, receiver_must_upper); + if (receiver_charset) + cet_convert_init(receiver_charset, 1); } static void rw_deinit(void) { if (mkshort_handle) { - mkshort_del_handle(mkshort_handle); - mkshort_handle = NULL; + mkshort_del_handle(&mkshort_handle); } } @@ -203,8 +253,10 @@ waypt_read(void) wpt_tmp->icon_descr = d103_symbol_from_icon_number( way[i]->smbl); } else { - wpt_tmp->icon_descr = mps_find_desc_from_icon_number( - way[i]->smbl, PCX); + int dyn = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number( + way[i]->smbl, PCX, &dyn); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = dyn; } /* * If a unit doesn't store altitude info (i.e. a D103) @@ -217,15 +269,18 @@ waypt_read(void) */ if ((way[i]->alt == (float) (1U<<31)) || (way[i]->alt == INT_MAX) || - (way[i]->alt == 1.0e25) + (way[i]->alt >= (float) 1.0e20) ) { wpt_tmp->altitude = unknown_alt; } else { wpt_tmp->altitude = way[i]->alt; } - if (way[i]->Time_populated) - wpt_tmp->creation_time = way[i]->Time; - + if (way[i]->time_populated) { + wpt_tmp->creation_time = way[i]->time; + } +#if SOON + garmin_fs_garmin_after_read(way[i], wpt_tmp, gps_waypt_type); +#endif waypt_add(wpt_tmp); GPS_Way_Del(&way[i]); } @@ -244,7 +299,7 @@ track_read(void) char trk_seg_num_buf[10]; char *trk_name = ""; - ntracks = GPS_Command_Get_Track(portname, &array); + ntracks = GPS_Command_Get_Track(portname, &array, waypt_read_cb); if ( ntracks <= 0 ) return; @@ -262,7 +317,6 @@ track_read(void) if (!trk_name) trk_name = ""; trk_seg_num = 1; - continue; } @@ -282,15 +336,20 @@ track_read(void) track_add_head(trk_head); } + if (array[i]->no_latlon || array[i]->ishdr) { + continue; + } wpt = waypt_new(); wpt->longitude = array[i]->lon; wpt->latitude = array[i]->lat; wpt->altitude = array[i]->alt; + wpt->heartrate = array[i]->heartrate; + wpt->cadence = array[i]->cadence; wpt->shortname = xstrdup(array[i]->trk_ident); wpt->creation_time = array[i]->Time; - route_add_wpt(trk_head, wpt); + track_add_wpt(trk_head, wpt); } while(ntracks) { @@ -306,7 +365,11 @@ route_read(void) int32 nroutepts; int i; GPS_PWay *array; - route_head *rte_head; + /* TODO: Fixes warning but is it right? + * RJL: No, the warning isn't right; GCC's flow analysis is broken. + * still, it's good taste... + */ + route_head *rte_head = NULL; nroutepts = GPS_Command_Get_Route(portname, &array); @@ -323,11 +386,11 @@ route_read(void) case 202: csrc = array[i]->rte_ident; break; default: break; } - rte_head = route_head_alloc(); - route_add_head(rte_head); - if (csrc) { - rte_head->rte_name = xstrdup(csrc); - } + rte_head = route_head_alloc(); + route_add_head(rte_head); + if (csrc) { + rte_head->rte_name = xstrdup(csrc); + } } else { if (array[i]->islink) { continue; @@ -346,6 +409,95 @@ route_read(void) } +/* + * Rather than propogate Garmin-specific data types outside of the Garmin + * code, we convert the PVT (position/velocity/time) data from the receiver + * to the data type we use throughout. Yes, we do lose some data that way. + */ +static void +pvt2wpt(GPS_PPvt_Data pvt, waypoint *wpt) +{ + double wptime, wptimes; + + wpt->altitude = pvt->alt; + wpt->latitude = pvt->lat; + wpt->longitude = pvt->lon; + + /* + * The unit reports time in three fields: + * 1) The # of days to most recent Sun. since 1989-12-31 midnight UTC. + * 2) The number of seconds (fractions allowed) since that Sunday. + * 3) The number of leap seconds that offset the current UTC and GPS + * reference clocks. + */ + wptime = 631065600.0 + pvt->wn_days * 86400.0 + + pvt->tow + - pvt->leap_scnds; + wptimes = floor(wptime); + wpt->creation_time = wptimes; + wpt->centiseconds = 100.0 * (wptime - wptimes); + + /* + * The Garmin spec fifteen different models that use a different + * table for 'fix' without a really good way to tell if the model + * we're talking to happens to be one of those...By inspection, + * it looks like even though the models (Summit, Legend, etc.) may + * be popular, it's older (2001 and earlier or so) versions that + * are affected and I think there are relatively few readers of + * the fix field anyway. Time will tell if this is a good plan. + */ + switch (pvt->fix) { + case 0: wpt->fix = fix_unknown;break; + case 1: wpt->fix = fix_none;break; + case 2: wpt->fix = fix_2d;break; + case 3: wpt->fix = fix_3d;break; + case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ + case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ + default: + /* undocumented type. */ + break; + } +} + +static gpsdevh *pvt_fd; + +static void +pvt_init(const char *fname) +{ + rw_init(fname); + GPS_Command_Pvt_On(fname, &pvt_fd); +} + +static waypoint * +pvt_read(posn_status *posn_status) +{ + waypoint *wpt = waypt_new(); + GPS_PPvt_Data pvt = GPS_Pvt_New(); + + if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { + pvt2wpt(pvt, wpt); + wpt->shortname = xstrdup("Position"); + + if (gps_errno && posn_status) { + posn_status->request_terminate = 1; + } + + return wpt; + } + + /* + * If the caller has not given us a better way to return the + * error, do it now. + */ + if (gps_errno) { + fatal(MYNAME ": Fatal error reading position.\n"); + } + + GPS_Pvt_Del(&pvt); + + return NULL; +} + static void data_read(void) { @@ -360,7 +512,7 @@ data_read(void) if (global_opts.masked_objective & RTEDATAMASK) route_read(); if (!(global_opts.masked_objective & - (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK))) + (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))) fatal(MYNAME ": Nothing to do.\n"); } @@ -484,12 +636,12 @@ waypoint_write(void) way[i]->lat = wpt->latitude; if (deficon) { - icon = mps_find_icon_number_from_desc(deficon, PCX); + icon = gt_find_icon_number_from_desc(deficon, PCX); } else { if (get_cache_icon(wpt)) { - icon = mps_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); } else { - icon = mps_find_icon_number_from_desc(wpt->icon_descr, PCX); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); } } @@ -501,11 +653,21 @@ waypoint_write(void) } way[i]->smbl = icon; if (wpt->altitude == unknown_alt) { + way[i]->alt_is_unknown = 1; way[i]->alt = 0; } else { way[i]->alt = wpt->altitude; } - way[i]->Time = wpt->creation_time; + if (wpt->creation_time) { + way[i]->time = wpt->creation_time; + way[i]->time_populated = 1; + } + if (category) { + way[i]->category = 1 << (atoi(category) - 1); + } +#if SOON + garmin_fs_garmin_before_write(wpt, way[i], gps_waypt_type); +#endif i++; } @@ -528,6 +690,10 @@ route_hdr_pr(const route_head *rte) { (*cur_tx_routelist_entry)->rte_num = rte->rte_num; (*cur_tx_routelist_entry)->isrte = 1; + if (rte->rte_name) { + strncpy((*cur_tx_routelist_entry)->rte_ident, rte->rte_name, + sizeof ((*cur_tx_routelist_entry)->rte_ident)); + } } static void @@ -542,14 +708,20 @@ route_waypt_pr(const waypoint *wpt) * we just double them up (sigh) and do that here. */ rte->islink = 1; + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; cur_tx_routelist_entry++; rte = *cur_tx_routelist_entry; rte->lon = wpt->longitude; rte->lat = wpt->latitude; - rte->smbl = mps_find_icon_number_from_desc(wpt->icon_descr, PCX); + rte->smbl = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + if (wpt->altitude != unknown_alt) { rte->alt = wpt->altitude; + } else { + rte->alt_is_unknown = 1; + rte->alt = 0; } strncpy(rte->ident, wpt->shortname, sizeof(rte->ident)); rte->ident[sizeof(rte->ident)-1] = 0; @@ -615,10 +787,7 @@ static void track_write(void) { int i; - /* Headers plus trackpoints. Trackpoints are added by - * route_add_waypt so get route_waypt_count() - */ - int n = route_waypt_count() + track_count(); + int n = track_waypt_count() + track_count(); tx_tracklist = xcalloc(n, sizeof(GPS_PTrack)); cur_tx_tracklist_entry = tx_tracklist; @@ -662,7 +831,9 @@ ff_vecs_t garmin_vecs = { data_read, data_write, NULL, - garmin_args + garmin_args, + CET_CHARSET_ASCII, 0, + { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } }; static const char *d103_icons[16] = { diff --git a/garmin_fs.c b/garmin_fs.c new file mode 100644 index 000000000..b22621ea3 --- /dev/null +++ b/garmin_fs.c @@ -0,0 +1,308 @@ +/* + + Implementation of special data used by Garmin products. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "inifile.h" + +#define MYNAME "garmin_fs" + +garmin_fs_t * +garmin_fs_alloc(const int protocol) +{ + garmin_fs_t *result = NULL; + + result = (garmin_fs_t *)xcalloc(1, sizeof(*result)); + result->fs.type = FS_GMSD; + result->fs.copy = (fs_copy) garmin_fs_copy; + result->fs.destroy = garmin_fs_destroy; + result->fs.convert = NULL; + result->fs.next = NULL; + + result->protocol = protocol; + + return result; +} + +void +garmin_fs_destroy(void *fs) +{ + garmin_fs_t *data = (garmin_fs_t *) fs; + if (data != NULL) + { + garmin_ilink_t *ilinks; + + if (data->city != NULL) xfree(data->city); + if (data->facility != NULL) xfree(data->facility); + if (data->state != NULL) xfree(data->state); + if (data->cc != NULL) xfree(data->cc); + if (data->cross_road != NULL) xfree(data->cross_road); + if ((ilinks = data->ilinks) != NULL) { + ilinks->ref_count--; + if (ilinks->ref_count <= 0) { + while (ilinks != NULL) { + garmin_ilink_t *tmp = ilinks; + ilinks = ilinks->next; + xfree(tmp); + } + } + } + xfree(data); + } +} + +void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src) +{ + if (src == NULL) + { + *dest = NULL; + return; + } + *dest = (garmin_fs_t *) xmalloc(sizeof(*src)); + + /* do not copy interlinks, only increment the refrence counter */ + if (src->ilinks != NULL) src->ilinks->ref_count++; + + memcpy(*dest, src, sizeof(*src)); + + (*dest)->city = (src->city != NULL) ? xstrdup(src->city) : NULL; + (*dest)->facility = (src->facility != NULL) ? xstrdup(src->facility) : NULL; + (*dest)->state = (src->state != NULL) ? xstrdup(src->facility) : NULL; + (*dest)->cc = (src->cc != NULL) ? xstrdup(src->cc) : NULL; + (*dest)->cross_road = (src->cross_road != NULL) ? xstrdup(src->cross_road) : NULL; + (*dest)->addr = (src->addr != NULL) ? xstrdup(src->addr) : NULL; +} + +/* GPX - out */ + +void +garmin_fs_xml_fprint(FILE *ofd, const waypoint *waypt) +{ + garmin_fs_t *gmsd = GMSD_FIND(waypt); + if (gmsd == NULL) return; + + if ((gmsd->flags.category && gmsd->category) || + gmsd->flags.depth || + gmsd->flags.proximity || + gmsd->flags.temperature || + gmsd->flags.display) + { + int space = 1; + + fprintf(ofd, "%*s\n", space++ * 2, ""); + fprintf(ofd, "%*s\n", space++ * 2, ""); + if (gmsd->flags.proximity) + fprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->proximity); + if (gmsd->flags.temperature) + fprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->temperature); + if (gmsd->flags.depth) + fprintf(ofd, "%*s%.6f\n", space * 2, "", gmsd->depth); + if (gmsd->flags.display) + { + char *cx; + switch(gmsd->display) + { + case gt_display_mode_symbol: + cx = "SymbolOnly"; + break; + case gt_display_mode_symbol_and_comment: + cx = "SymbolAndDescription"; + break; + default: + cx = "SymbolAndName"; + break; + } + fprintf(ofd, "%*s%s\n", space * 2, "", cx); + } + if (gmsd->flags.category && gmsd->category) + { + int i; + gbuint16 cx = gmsd->category; + fprintf(ofd, "%*s\n", space++ * 2, ""); + for (i = 0; i < 16; i++) + { + if (cx & 1) + fprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); + cx = cx >> 1; + } + fprintf(ofd, "%*s\n", --space * 2, ""); + } + fprintf(ofd, "%*s\n", --space * 2, ""); + fprintf(ofd, "%*s\n", --space * 2, ""); + } + +} + +void +garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt) +{ + garmin_fs_t *gmsd; + + gmsd = GMSD_FIND(waypt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); + } + + tag -= base_tag; +/* + tt_garmin_extension, -> 0 + tt_garmin_waypt_extension, -> 1 + tt_garmin_proximity, -> 2 + tt_garmin_temperature,-> 3 + tt_garmin_depth, -> 4 + tt_garmin_display_mode, -> 5 + tt_garmin_categories, -> 6 + tt_garmin_category, -> 7 +*/ + switch(tag) { + case 2: GMSD_SET(proximity, atof(cdatastr)); break; + case 3: GMSD_SET(temperature, atof(cdatastr)); break; + case 4: GMSD_SET(depth, atof(cdatastr)); break; + case 5: if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } + else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } + else { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + case 7: if ( ! garmin_fs_merge_category(cdatastr, waypt)) { + warning(MYNAME ": Unable to convert category \"%s \"!\n", cdatastr); + } + break; + } +} + +unsigned char +garmin_fs_convert_category(const char *category_name, gbuint16 *category) +{ + int i; + int cat = 0; + + if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && + (1 == sscanf(category_name + 9, "%d", &i)) && + (i >= 1) && (i <= 16)) { + cat = (1 << --i); + } + else if (global_opts.inifile != NULL) { + for (i = 0; i < 16; i++) { + char *c; + char key[3]; + + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + if ((c != NULL) && (case_ignore_strcmp(c, category_name) == 0)) { + cat = (1 << i); + break; + } + } + } + if (cat == 0) { + return 0; + } + else { + *category = cat; + return 1; + } +} + +unsigned char +garmin_fs_merge_category(const char *category_name, waypoint *waypt) +{ + gbuint16 cat; + garmin_fs_t *gmsd; + + if (!garmin_fs_convert_category(category_name, &cat)) { + return 0; + } + + gmsd = GMSD_FIND(waypt); + cat = cat | ( GMSD_GET(category, 0) ); + + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); + } + GMSD_SET(category, cat); + return 1; +} + +void +garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid) +{ + garmin_fs_t *gmsd = NULL; + + gmsd = garmin_fs_alloc(protoid); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + /* nothing happens until gmsd is allocated some lines above */ + + /* !!! class needs protocol specific conversion !!! (ToDo) + GMSD_SET(wpt_class, way[i]->wpt_class); + */ + /* flagged data fields */ + GMSD_SET(display, gt_switch_display_mode_value(way->dspl, gps_waypt_type, 1)); + if (way->category != 0) GMSD_SET(category, way->category); + if (way->dst < 1.0e25f) GMSD_SET(proximity, way->dst); + if (way->temperature_populated) GMSD_SET(temperature, way->temperature); + if (way->dpth < 1.0e25f) GMSD_SET(depth, way->dpth); + GMSD_SETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_SETNSTR(state, way->state, sizeof(way->state)); + GMSD_SETSTR(city, way->city); + GMSD_SETSTR(facility, way->facility); + GMSD_SETSTR(cross_road, way->cross_road); + GMSD_SETSTR(addr, way->addr); +} + +void +garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid) +{ + garmin_fs_t *gmsd = GMSD_FIND(wpt); + + if (gmsd == NULL) return; + + /* ToDo: protocol specific conversion of class + way[i]->wpt_class = GMSD_GET(wpt_class, way[i]->wpt_class); + */ + way->dspl = gt_switch_display_mode_value( + GMSD_GET(display, way->dspl), gps_waypt_type, 0); + way->category = GMSD_GET(category, way->category); + way->dpth = GMSD_GET(depth, way->dpth); + way->dst = GMSD_GET(proximity, way->dpth); + way->temperature = GMSD_GET(temperature, way->temperature); + + GMSD_GETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_GETNSTR(city, way->city, sizeof(way->city)); + GMSD_GETNSTR(state, way->state, sizeof(way->state)); + GMSD_GETNSTR(facility, way->facility, sizeof(way->facility)); + GMSD_GETNSTR(cross_road, way->cross_road, sizeof(way->cross_road)); + GMSD_GETNSTR(addr, way->addr, sizeof(way->addr)); +} + diff --git a/garmin_fs.h b/garmin_fs.h new file mode 100644 index 000000000..123525123 --- /dev/null +++ b/garmin_fs.h @@ -0,0 +1,124 @@ +/* + + Implementation of special data used by Garmin products. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef GARMIN_FS_H +#define GARMIN_FS_H + +#include +#include "defs.h" +#include "jeeps/gps.h" + +/* this order is used by most devices */ +/* typedef enum { + garmin_display_symbol_and_name = 0, + garmin_display_symbol_only = 1, + garmin_display_symbol_and_description = 2 +} garmin_display_t; +*/ + +/* macros */ + +#define GMSD_FIND(a) (garmin_fs_t *) fs_chain_find((a)->fs, FS_GMSD) + +/* GMSD_GET(a,b): a = any gmsd field, b = default value */ +#define GMSD_GET(a,b) ((gmsd) && (gmsd->flags.a)) ? (gmsd->a) : (b) + +/* GMSD_SET(a,b): a = numeric gmsd field, b = numeric source */ +#define GMSD_SET(a,b) if (gmsd) {gmsd->a = (b); gmsd->flags.a = 1; } + +/* GMSD_SETSTR(a,b): a = gmsd field, b = null terminated source */ +#define GMSD_SETSTR(a,b) if (gmsd && (b) && (b)[0]) { gmsd->a = xstrdup((b)); gmsd->flags.a = 1; } + +/* GMSD_SETNSTR(a,b,c): a = gmsd field, b = source, c = sizeof(source) */ +#define GMSD_SETNSTR(a,b,c) if (gmsd && (b) && (b)[0]) { gmsd->a = xstrndup((b),(c)); gmsd->flags.a = 1; } + +/* GMSD_GETNSTR(a,b,c): a = gmsd field, b = target, c = sizeof(target) */ +#define GMSD_GETNSTR(a,b,c) if (gmsd && gmsd->flags.a) strncpy((b),gmsd->a,(c)) + +typedef struct garmin_ilink_s { + int ref_count; + double lat, lon; + struct garmin_ilink_s *next; +} garmin_ilink_t; + +typedef struct { + unsigned int icon:1; + unsigned int wpt_class:1; + unsigned int display:1; + unsigned int category:1; + unsigned int depth:1; + unsigned int proximity:1; + unsigned int temperature:1; + unsigned int city:1; + unsigned int state:1; + unsigned int facility:1; + unsigned int cc:1; + unsigned int cross_road:1; + unsigned int addr:1; +} garmin_fs_flags_t; + +typedef struct garmin_fs_s +{ + format_specific_data fs; + garmin_fs_flags_t flags; + + int protocol; /* ... used by device (-1 is MapSource) */ + + gbint32 icon; + int wpt_class; + gbint32 display; + gbint16 category; + double depth; /* depth in meters */ + double proximity; /* proximity distance in meters */ + double temperature; + char *city; /* city name */ + char *facility; /* facility name */ + char *state; /* state */ + char *cc; /* country code */ + char *cross_road; /* Intersection road label */ + char *addr; /* address + number */ + garmin_ilink_t *ilinks; +} garmin_fs_t, *garmin_fs_p; + +garmin_fs_t *garmin_fs_alloc(const int protocol); +void garmin_fs_destroy(void *fs); +void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src); +char *garmin_fs_xstrdup(const char *src, size_t size); + +/* for GPX */ +void garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt); +void garmin_fs_xml_fprint(FILE *ofd, const waypoint *waypt); + +/* common garmin_fs utilities */ + +/* ..convert_category: returns 1=OK; 0=Unable to convert category */ +unsigned char garmin_fs_convert_category(const char *category_name, gbuint16 *category); + +/* ..merge_category: returns 1=OK; 0=Unable to convert category */ +unsigned char garmin_fs_merge_category(const char *category_name, waypoint *waypt); + +#define GMSD_SECTION_CATEGORIES "Garmin Categories" + +void garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid); +void garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid); + +#endif diff --git a/garmin_tables.c b/garmin_tables.c index 2a63833f7..5e0811f9c 100644 --- a/garmin_tables.c +++ b/garmin_tables.c @@ -22,6 +22,9 @@ #include "garmin_tables.h" #include +#include + +#define MYNAME "garmin_tables" /* MapSource 4.13 */ icon_mapping_t garmin_icon_table[] = { @@ -170,41 +173,15 @@ icon_mapping_t garmin_icon_table[] = { { 35, 36, "White Dot" }, { 88, 8219, "Zoo" }, - /* These are experimental and for the custom icons in the new "C" - * models. As of this writing, firmware problems impair their - * general use. - * - * "Quest" supports more icons than this, but other problems - * prohibit us from running with that model, so we stop at 24. - * - * Mapsource doesn't yet know how to do these, so we made the icon - * numbers "-2" to signify that as a problem until we can create - * these in a .mps or .gdb file and see their representation there. + /* Custom icons. The spec reserves 7680-8191 for the custom + * icons on the C units, Quest, 27xx, 276, 296, and other units. + * Note that firmware problems on the earlier unit result in these + * being mangled, so be sure you're on a version from at least + * late 2005. + * { -2, 7680, "Custom 0" }, + * .... + * { -2, 8192, "Custom 511" }, */ - { -2, 7680, "Custom 0" }, - { -2, 7681, "Custom 1" }, - { -2, 7682, "Custom 2" }, - { -2, 7683, "Custom 3" }, - { -2, 7684, "Custom 4" }, - { -2, 7685, "Custom 5" }, - { -2, 7686, "Custom 6" }, - { -2, 7687, "Custom 7" }, - { -2, 7688, "Custom 8" }, - { -2, 7689, "Custom 9" }, - { -2, 7690, "Custom 10" }, - { -2, 7691, "Custom 11" }, - { -2, 7692, "Custom 12" }, - { -2, 7693, "Custom 13" }, - { -2, 7694, "Custom 14" }, - { -2, 7695, "Custom 15" }, - { -2, 7696, "Custom 16" }, - { -2, 7697, "Custom 17" }, - { -2, 7698, "Custom 18" }, - { -2, 7699, "Custom 19" }, - { -2, 7700, "Custom 20" }, - { -2, 7701, "Custom 21" }, - { -2, 7702, "Custom 22" }, - { -2, 7703, "Custom 23" }, { 92, 8227, "Micro-Cache" }, /* icon for "Toll Booth" */ { 48, 161, "Virtual cache" }, /* icon for "Scenic Area" */ @@ -239,6 +216,554 @@ icon_mapping_t garmin_icon_table[] = { { 159, 188, "Weed Bed" }, { 160, 189, "Dropoff" }, { 161, 190, "Dock" }, + + /* New in Garmin protocol spec from June 2006. Extracted from + * spec and fed through some horrible awk to add ones we didn't + * have before but normalized for consistency. */ + { -1, 8359, "Asian Food" }, + { -1, 8296, "Blue Circle" }, + { -1, 8299, "Blue Diamond" }, + { -1, 8317, "Blue Letter A" }, + { -1, 8318, "Blue Letter B" }, + { -1, 8319, "Blue Letter C" }, + { -1, 8320, "Blue Letter D" }, + { -1, 8341, "Blue Number 0" }, + { -1, 8342, "Blue Number 1" }, + { -1, 8343, "Blue Number 2" }, + { -1, 8344, "Blue Number 3" }, + { -1, 8345, "Blue Number 4" }, + { -1, 8346, "Blue Number 5" }, + { -1, 8347, "Blue Number 6" }, + { -1, 8348, "Blue Number 7" }, + { -1, 8349, "Blue Number 8" }, + { -1, 8350, "Blue Number 9" }, + { -1, 8302, "Blue Oval" }, + { -1, 8305, "Blue Rectangle" }, + { -1, 8308, "Blue Square" }, + { -1, 8351, "Blue Triangle" }, + { -1, 8254, "Border Crossing (Port Of Entry)" }, + { -1, 182, "Bottom Conditions" }, + { -1, 8360, "Deli" }, + { -1, 8228, "Elevation point" }, + { -1, 8229, "Exit without services" }, + { -1, 16398, "First approach fix" }, + { -1, 8250, "Gambling/casino" }, + { -1, 8232, "Geographic place name, land" }, + { -1, 8230, "Geographic place name, Man-made" }, + { -1, 8231, "Geographic place name, water" }, + { -1, 8295, "Green circle" }, + { -1, 8313, "Green Letter A" }, + { -1, 8315, "Green Letter B" }, + { -1, 8314, "Green Letter C" }, + { -1, 8316, "Green Letter D" }, + { -1, 8331, "Green Number 0" }, + { -1, 8332, "Green Number 1" }, + { -1, 8333, "Green Number 2" }, + { -1, 8334, "Green Number 3" }, + { -1, 8335, "Green Number 4" }, + { -1, 8336, "Green Number 5" }, + { -1, 8337, "Green Number 6" }, + { -1, 8338, "Green Number 7" }, + { -1, 8339, "Green Number 8" }, + { -1, 8340, "Green Number 9" }, + { -1, 8301, "Green Oval" }, + { -1, 8304, "Green Rectangle" }, + { -1, 8352, "Green Triangle" }, + { -1, 16385, "Intersection" }, + { -1, 8201, "Intl freeway hwy" }, + { -1, 8202, "Intl national hwy" }, + { -1, 8361, "Italian food" }, + { -1, 8248, "Large exit without services" }, + { -1, 8247, "Large Ramp intersection" }, + { -1, 16399, "Localizer Outer Marker" }, + { -1, 16400, "Missed approach point" }, + { -1, 16386, "Non-directional beacon" }, + { -1, 168, "Null" }, + { -1, 180, "Open 24 Hours" }, + { -1, 8222, "Ramp intersection" }, + { -1, 8294, "Red circle" }, + { -1, 8309, "Red Letter A" }, + { -1, 8310, "Red Letter B" }, + { -1, 8311, "Red Letter C" }, + { -1, 8312, "Red Letter D" }, + { -1, 8321, "Red Number 0" }, + { -1, 8322, "Red Number 1" }, + { -1, 8323, "Red Number 2" }, + { -1, 8324, "Red Number 3" }, + { -1, 8325, "Red Number 4" }, + { -1, 8326, "Red Number 5" }, + { -1, 8327, "Red Number 6" }, + { -1, 8328, "Red Number 7" }, + { -1, 8329, "Red Number 8" }, + { -1, 8330, "Red Number 9" }, + { -1, 8300, "Red Oval" }, + { -1, 8303, "Red Rectangle" }, + { -1, 8353, "Red Triangle" }, + { -1, 8362, "Seafood" }, + { -1, 8194, "State Hwy" }, + { -1, 8363, "Steak" }, + { -1, 8223, "Street Intersection" }, + { -1, 16401, "TACAN" }, + { -1, 183, "Tide/Current PRediction Station" }, + { -1, 191, "U Marina" }, + { -1, 8193, "US hwy" }, + { -1, 193, "U stump" }, + { -1, 16387, "VHF Omni-range" }, + { -1, 16397, "VOR-DME" }, + { -1, 16396, "VOR/TACAN" }, { -1, -1, NULL }, }; + +/* ICAO coutry code table */ + +/* source: http://en.wikipedia.org/wiki/ICAO_airport_code */ + +gt_country_code_t gt_country_codes[] = +{ + { "ZM,", "Mongolia" }, + { "ZK,", "North Korea" }, + { "Z*,", "China" }, + { "Y*,", "Australia" }, + { "WS,", "Singapore" }, + { "WM,", "Brunei/Malaysia" }, + { "WB,", "Malaysia" }, + { "WA,WI,WQ,WR,", "Indonesia" }, + { "VV,", "Vietnam" }, + { "VT,", "Thailand" }, + { "VR,", "Maldives" }, + { "VQ,", "Bhutan" }, + { "VN,", "Nepal" }, + { "VM,", "Macau" }, + { "VL,", "Laos" }, + { "VH,", "Hong Kong" }, + { "VG,", "Bangladesh" }, + { "VD,", "Kampuchea" }, + { "VC,", "Sri Lanka" }, + { "VB,VY,", "Myanmar/Burma" }, + { "VA,VE,VI,VO,", "India" }, + { "UR,", "Kazakhstan/Russia" }, + { "UT,", "Kazakhstan/Tadzhikistan/Turkmenistan/Uzbekistan" }, + { "UM,", "Belorussia/Russia" }, + { "UK,", "Ukraine" }, + { "UB,", "Azerbaijan" }, + { "UA,", "Kazakhstan/Kirgizia" }, + { "U*,", "Russia" }, + { "TX,", "Bermuda" }, + { "TV,", "St Vincent and the Grenadines" }, + { "TU,", "British Virgin Islands" }, + { "TT,", "Trinidad and Tobago" }, + { "TR,", "Montserrat Island" }, + { "TQ,", "Anguilla" }, + { "TN,", "Aruba/Neth Antilles" }, + { "TL,", "St Lucia" }, + { "TK,", "St Kitts/Nevis Islands" }, + { "TJ,", "Puerto Rico" }, + { "TG,", "Grenada" }, + { "TF,", "Guadeloupe/Martinique" }, + { "TD,", "Dominica" }, + { "TB,", "Barbados" }, + { "TA,", "Antigua" }, + { "SY,", "Guyana" }, + { "SV,", "Venezuela" }, + { "SU,", "Uruguay" }, + { "SP,", "Peru" }, + { "SO,", "French Guiana" }, + { "SM,", "Suriname" }, + { "SL,", "Bolivia" }, + { "SK,", "Colombia/San Andres" }, + { "SG,", "Paraguay" }, + { "SF,", "Falkland Islands" }, + { "SE,", "Ecuador" }, + { "SC,", "Chile/Easter Island" }, + { "SB,SD,SN,SS,SW,", "Brazil" }, + { "SA,", "Argentina" }, + { "S1,", "Antarctica (Argentina/Chile)" }, + { "RP,", "Philippines" }, + { "RK,", "South Korea" }, + { "RJ,", "Japan" }, + { "RC,", "Taiwan" }, + { "PW,", "Wake Island" }, + { "PT,", "Caroline Islands/Micronesia/Palau" }, + { "PM,", "Midway Islands" }, + { "PK,", "Marshall Islands" }, + { "PJ,", "Johnston Atoll" }, + { "PG,", "Guam/Mariana Islands/Northern Mariana Islands" }, + { "PC,", "Kiribati" }, + { "P", "Oakland Octa" }, + { "OY,", "Yemen Arab Rep" }, + { "OT,", "Qatar" }, + { "OS,", "Syria" }, + { "OR,", "Iraq" }, + { "OP,", "Pakistan" }, + { "OO,", "Oman" }, + { "OM,", "United Arab Emirates" }, + { "OL,", "Lebanon" }, + { "OK,", "Kuwait" }, + { "OJ,", "Jordan" }, + { "OI,", "Iran" }, + { "OE,", "Saudi Arabia" }, + { "OB,", "Bahrain" }, + { "OA,", "Afghanistan" }, + { "NZ,PL,", "New Zealand" }, + { "NW,", "New Caledonia" }, + { "NV,", "Vanuatu" }, + { "NT,", "French Polynesia/Society Islands/Tuamotu Islands" }, + { "NS,", "American Samoa/Western Samoa" }, + { "NL,", "Futuna Island/Wallis Island" }, + { "NI,", "Niue" }, + { "NG,", "Kiribati/Tuvalu" }, + { "NF,", "Fiji Island/Tonga" }, + { "NC,", "Cook Islands" }, + { "MZ,", "Belize" }, + { "MY,", "Bahamas" }, + { "MW,", "Cayman Islands" }, + { "MU,", "Cuba" }, + { "MT,", "Haiti" }, + { "MS,", "El Salvador" }, + { "MR,", "Costa rica" }, + { "MP,", "Panama" }, + { "MN,", "Nicaragua" }, + { "MM,", "Mexico" }, + { "MK,", "Jamaica" }, + { "MI,TI,", "Virgin Islands (U.S.)" }, + { "MH,", "Honduras" }, + { "MG,", "Guatemala" }, + { "MD,", "Dominican Republic" }, + { "MB,", "Turks Island/Caicos Island" }, + { "LZ,", "Slovakia" }, + { "LY,", "Yugoslavia" }, + { "LX,", "Gibraltar" }, + { "LW,", "Macedonia" }, + { "LV,", "Gaza" }, + { "LU,", "Moldova" }, + { "LT,", "Turkey" }, + { "LS,", "Switzerland" }, + { "LR,", "Romania" }, + { "LQ,", "Bosnia-Herzegovina" }, + { "LP,", "Portugal/Azores/Madeira Islands" }, + { "LO,", "Austria" }, + { "LN,", "Monaco" }, + { "LM,", "Malta" }, + { "LL,", "Israel/Jerusalem" }, + { "LK,", "Czech" }, + { "LI,", "Italy" }, + { "LH,", "Hungary" }, + { "LG,", "Slovenia" }, + { "LG,", "Greece" }, + { "LF,", "France" }, + { "LF,", "Miquelon Island/St Pierre Island" }, + { "LE,", "Spain" }, + { "LD,", "Croatia" }, + { "LC,", "Cyprus/Turkey (Northern Cyprus)" }, + { "LB,", "Bulgaria" }, + { "LA,", "Albania" }, + { "K*,X*,PA,PB,PF,PJ,PL,PM,PO,PP,PH,PW,", "United States of America" }, + { "HU,", "Uganda" }, + { "HT,", "Tanzania" }, + { "HS,", "Sudan" }, + { "HR,", "Rwanda" }, + { "HL,", "Libya, Spa Jamahiriya" }, + { "HK,", "Kenya" }, + { "HH,", "Eritrea" }, + { "HE,", "Egypt" }, + { "HD,HF,", "Djibouti" }, + { "HC,", "Somalia" }, + { "HB,", "Burundi" }, + { "HA,", "Ethiopia" }, + { "GV,", "Cape Verde" }, + { "GU,", "Guinea Tepublic" }, + { "GQ,", "Mauritania" }, + { "GO,", "Senegal" }, + { "GM,", "Morocco/Ad Dakhla/La'Youn" }, + { "GL,", "Liberia" }, + { "GG,", "Guinea-Bissau" }, + { "GF,", "Sierra Leone" }, + { "GE,", "Melilla" }, + { "GC,", "Canary Island" }, + { "GB,", "Gambia" }, + { "GA,", "Mali" }, + { "FZ,", "Democratic Republic of Congo" }, + { "FY,", "Namibia" }, + { "FX,", "Lesotho" }, + { "FW,", "Malawi" }, + { "FV,", "Zimbabwe" }, + { "FT,", "Chad" }, + { "FS,", "Seychelles" }, + { "FQ,", "Mozambique" }, + { "FP,", "Sao Tome & Principe" }, + { "FO,", "Gabon" }, + { "FN,", "Angola" }, + { "FM,", "Madagascar/Comoros/Reunion/Mayotte Islands" }, + { "FL,", "Zambia" }, + { "FK,", "Cameroon" }, + { "FJ,", "Chagos Archipelago/British Indian Ocean Territory" }, + { "FI,", "Mauritius" }, + { "FH,", "Ascension Island/St Helena Island" }, + { "FG,", "Equitorial Guinea" }, + { "FE,", "Central African Republic" }, + { "FD,", "Swaziland" }, + { "FC,", "Congo" }, + { "FB,", "Botswana" }, + { "FA,", "South African Republic" }, + { "EY,", "Lithuania" }, + { "EV,", "Latvia" }, + { "ES,", "Sweden" }, + { "EP,", "Poland" }, + { "EN,", "Norway" }, + { "EL,", "Luxembourg" }, + { "EK,", "Denmark/Faroe Island" }, + { "EI,", "Ireland" }, + { "EH,", "Netherlands" }, + { "EG,LX,", "United Kingdom" }, + { "EF,", "Finland" }, + { "EE,", "Estonia" }, + { "ED,ET,", "Germany" }, + { "EB,", "Belgium" }, + { "DX,", "Togo" }, + { "DT,", "Tunisia" }, + { "DR,", "Niger" }, + { "DN,", "Nigeria" }, + { "DI,", "Ivory Coast" }, + { "DG,", "Ghana" }, + { "DF,", "Burkina Faso" }, + { "DB,", "Benin" }, + { "DA,", "Algeria" }, + { "C*,", "Canada" }, + { "BI,", "Iceland" }, + { "BG,", "Greenland" }, + { "AY,", "Papua New Guinea" }, + { "AN,", "Nauru" }, + { "AG,", "Solomon Island" }, + { NULL, NULL } +}; + +/* gt_waypt_classes: gdb internal order */ +char *gt_waypt_class_names[] = { + "User Waypoint", + "Airport", + "Intersection", + "NDB", + "VOR", + "Runway Threshold", + "Airport Intersection", + "Airport NDB", + "Map Point", + "Map Area", + "Map Intersection", + "Map Address", + "Map Line", + NULL +}; + +/* gt_display_mode_names: this order is used by most devices */ +char *gt_display_mode_names[] = { + "Symbol & Name", + "Symbol", + "Symbol & Description" +}; + +unsigned char +gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device) +{ + if (device) { + switch(protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: return display_mode & 3; + case 104: + switch(display_mode) { + case 0: + case 1: return gt_display_mode_symbol; + case 3: return gt_display_mode_symbol_and_name; + case 5: return gt_display_mode_symbol_and_comment; + } + case 155: + switch(display_mode) { + case 1: return gt_display_mode_symbol; + case 3: return gt_display_mode_symbol_and_name; + case 5: return gt_display_mode_symbol_and_comment; + } + } + return gt_display_mode_symbol_and_name; + } else { + switch(protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: return display_mode & 3; + case 104: + case 155: + switch(display_mode) { + case gt_display_mode_symbol: return 1; + case gt_display_mode_symbol_and_name: return 3; + case gt_display_mode_symbol_and_comment: return 5; + } + } + return 0; + } +} + +char * +gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic) +{ + icon_mapping_t *i; + char custom[] = "Custom 63 "; + + if ((garmin_format == GDB) && (icon >= 500) && (icon <= 563)) + { + snprintf(custom, sizeof(custom), "Custom %d", icon - 500); + *dynamic = 1; + return xstrdup(custom); + } + + if ((garmin_format == PCX) && (icon >= 7680) && (icon <= 8191)) { + snprintf(custom, sizeof(custom), "Custom %d", icon - 7680); + *dynamic = 1; + return xstrdup(custom); + } + + if (dynamic) *dynamic = 0; + + for (i = garmin_icon_table; i->icon; i++) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + if (icon == i->mpssymnum) + return (char *)i->icon; + break; + case PCX: + case GARMIN_SERIAL: + if (icon == i->pcxsymnum) + return (char *)i->icon; + break; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + return DEFAULT_ICON_DESCR; +} + +int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) +{ + icon_mapping_t *i; + int def_icon = DEFAULT_ICON_VALUE; + int n; + + if (!desc) + return def_icon; + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + if (0 == case_ignore_strncmp(desc, "Custom ", 7)) { + int base = 0; + if (garmin_format == GDB) base = 500; + if (garmin_format == PCX) base = 7680; + if (base) { + n = atoi(&desc[7]); + return n + base; + } + } + + for (i = garmin_icon_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + return i->mpssymnum; + case PCX: + case GARMIN_SERIAL: + return i->pcxsymnum; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + } + return def_icon; +} + +char * +gt_get_icao_country(const char *cc) +{ + gt_country_code_t *x = >_country_codes[0]; + + if ((cc == NULL) || (*cc == '\0')) return NULL; + + do { + char *ccx = x->cc; + while (ccx != NULL) { + if (strncmp(ccx, cc, 2) == 0) return x->country; + if ((ccx[0] == cc[0]) && (ccx[1] == '*')) return x->country; + ccx = strchr(ccx, ','); + if (ccx == NULL) break; + ccx++; + } + x++; + } while (x->cc != NULL); + return NULL; +} + +char * +gt_get_icao_cc(const char *country, const char *shortname) +{ + static char res[3]; + gt_country_code_t *x = >_country_codes[0]; + + if ((country == NULL) || (*country == '\0')) { + char *test; + if (shortname == NULL) return NULL; + switch(strlen(shortname)) { + case 3: strncpy(res, shortname, 1); break; + case 4: strncpy(res, shortname, 2); break; + default: return NULL; + } + test = gt_get_icao_country(res); + if (test != NULL) + return res; + else + return NULL; + } + + do { + if (case_ignore_strcmp(country, x->country) != 0) { + x++; + continue; + } + + if (strlen(x->cc) <= 3) { + strncpy(res, x->cc, 3); + if (res[1] == '*') + res[1] = '\0'; + else + res[2] = '\0'; + return res; + } + if (shortname && (strlen(shortname) == 4)) { + char *ccx = x->cc; + + strncpy(res, shortname, 2); + res[2] = '\0'; + while (ccx != NULL) { + if (strncmp(ccx, res, 2) == 0) return res; + if ((ccx[0] == res[0]) && (ccx[1] == '*')) return res; + ccx = strchr(ccx, ','); + if (ccx == NULL) break; + ccx++; + } + } + return NULL; + } while (x->country != NULL); + return NULL; +} diff --git a/garmin_tables.h b/garmin_tables.h index 9b58383cb..79667843c 100644 --- a/garmin_tables.h +++ b/garmin_tables.h @@ -20,19 +20,76 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ +#ifndef GARMIN_TABLES_H +#define GARMIN_TABLES_H + +#include "defs.h" + +#define DEFAULT_ICON_DESCR "Waypoint" +#define DEFAULT_ICON_VALUE 18 + typedef struct icon_mapping { const int mpssymnum; const int pcxsymnum; const char *icon; } icon_mapping_t; -typedef enum {MAPSOURCE, PCX, GARMIN_SERIAL} garmin_formats_e; +typedef enum {MAPSOURCE, PCX, GARMIN_SERIAL, GDB} garmin_formats_e; -extern const -char *mps_find_desc_from_icon_number(const int icon, - garmin_formats_e garmin_format); -extern int -mps_find_icon_number_from_desc(const char *desc, - garmin_formats_e garmin_format); +char *gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic); +int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format); extern icon_mapping_t garmin_icon_table[]; + +typedef enum { + gt_waypt_class_user_waypoint = 0, + gt_waypt_class_airport, + gt_waypt_class_intersection, + gt_waypt_class_ndb, + gt_waypt_class_vor, + gt_waypt_class_runway_threshold, + gt_waypt_class_airport_intersection, + gt_waypt_class_airport_ndb, + gt_waypt_class_map_point, + gt_waypt_class_map_area, + gt_waypt_class_map_intersection, + gt_waypt_class_map_address, + gt_waypt_class_map_line +} gt_waypt_classes_e; + +extern char *gt_waypt_class_names[]; + +typedef struct gt_country_code_s +{ + char *cc; + char *country; +} gt_country_code_t; + +extern gt_country_code_t gt_country_codes[]; + +char *gt_get_icao_country(const char *cc); +char *gt_get_icao_cc(const char *country, const char *shortname); + +/* this order is used by most devices */ +typedef enum { + gt_display_mode_symbol_and_name = 0, + gt_display_mode_symbol, + gt_display_mode_symbol_and_comment +} gt_display_modes_e; + +extern char *gt_display_mode_names[]; + +#define GT_DISPLAY_MODE_MIN gt_display_mode_symbol_and_name +#define GT_DISPLAY_MODE_MAX gt_display_mode_symbol_and_comment + +typedef enum { + gt_gdb_display_mode_symbol = 0, + gt_gdb_display_mode_symbol_and_name, + gt_gdb_display_mode_symbol_and_comment +} gt_gdb_display_modes_e; + +unsigned char gt_convert_category(const char *name, int *category); + +unsigned char gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device); + +#endif diff --git a/garmin_txt.c b/garmin_txt.c new file mode 100644 index 000000000..9de5d56e7 --- /dev/null +++ b/garmin_txt.c @@ -0,0 +1,1272 @@ +/* + + Support for MapSource Text Export (Tab delimited) files. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#if CSVFMTS_ENABLED +#include +#include +#include +#include +#include +#include "cet_util.h" +#include "csv_util.h" +#include "garmin_fs.h" +#include "garmin_tables.h" +#include "grtcirc.h" +#include "inifile.h" +#include "jeeps/gpsmath.h" +#include "strptime.h" + +#define MYNAME "garmin_txt" + +typedef struct gtxt_flags_s { + unsigned int metric:1; + unsigned int celsius:1; + unsigned int utc:1; + unsigned int enum_waypoints:1; + unsigned int route_header_written:1; + unsigned int track_header_written:1; +} gtxt_flags_t; + +static gbfile *fin, *fout; +static route_head *current_trk, *current_rte; +static int waypoints; +static int routepoints; +static waypoint **wpt_a; +static int wpt_a_ct; +static int grid_index; +static int datum_index; +static char *datum_str; +static int current_line; +static char *date_time_format = NULL; +static int precision = 3; +static time_t utc_offs = 0; + +static gtxt_flags_t gtxt_flags; + +typedef enum { + waypt_header = 0, + rtept_header, + trkpt_header, + route_header, + track_header, + unknown_header +} header_type; + +#define MAX_HEADER_FIELDS 24 + +static char *header_lines[unknown_header + 1][MAX_HEADER_FIELDS]; +static int header_fields[unknown_header + 1][MAX_HEADER_FIELDS]; +static int header_ct[unknown_header + 1]; + +#define GARMIN_UNKNOWN_ALT 1.0e25f +#define DEFAULT_DISPLAY garmin_display_symbol_and_name +#define DEFAULT_DATE_FORMAT "dd/mm/yyyy" +#define DEFAULT_TIME_FORMAT "HH:mm:ss" + +/* macros */ + +#define IS_VALID_ALT(a) (((a) != unknown_alt) && ((a) < GARMIN_UNKNOWN_ALT)) +#define DUPSTR(a) (((a) != NULL) && ((a)[0] != 0)) ? xstrdup((a)) : NULL + +static char *opt_datum = NULL; +static char *opt_dist = NULL; +static char *opt_temp = NULL; +static char *opt_date_format = NULL; +static char *opt_time_format = NULL; +static char *opt_precision = NULL; +static char *opt_utc = NULL; + +static +arglist_t garmin_txt_args[] = { + {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, + {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, + {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, + {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, + {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"utc", &opt_utc, "Write timestamps with offset x to UTC time", NULL, ARGTYPE_INT, "-23", "+23"}, + ARG_TERMINATOR +}; + +typedef struct info_s +{ + double length; + time_t start; + time_t time; + double speed; + double total; + int count; + waypoint *prev_wpt; + waypoint *first_wpt; + waypoint *last_wpt; +} info_t; + +static info_t *route_info; +static int route_idx; +static info_t *cur_info; + +static char *headers[] = { + "Name\tDescription\tType\tPosition\tAltitude\tDepth\tProximity\tTemperature\t" + "Display Mode\tColor\tSymbol\tFacility\tCity\tState\tCountry\t" + "Date Modified\tLink\tCategories", + "Waypoint Name\tDistance\tLeg Length\tCourse", + "Position\tTime\tAltitude\tDepth\tLeg Length\tLeg Time\tLeg Speed\tLeg Course", + "Name\tLength\tCourse\tWaypoints\tLink", + "Name\tStart Time\tElapsed Time\tLength\tAverage Speed\tLink", + NULL +}; + +/* helpers */ + +static char * +get_option_val(char *option, char *def) +{ + char *c = (option != NULL) ? option : def; + return c; +} + +static void +init_date_and_time_format(void) +{ + char *f, *c; + + f = get_option_val(opt_date_format, DEFAULT_DATE_FORMAT); + date_time_format = convert_human_date_format(f); + + date_time_format = xstrappend(date_time_format, " "); + + f = get_option_val(opt_time_format, DEFAULT_TIME_FORMAT); + c = convert_human_time_format(f); + date_time_format = xstrappend(date_time_format, c); + xfree(c); +} + +static double +distance(double lat1, double lon1, double lat2, double lon2) +{ + double res = radtometers(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); + if (res < 0.1) res = 0; /* calc. diffs on 32- and 64-bit hosts */ + return res; +} + +static double +course_deg(double lat1, double lon1, double lat2, double lon2) +{ + return DEG(heading(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); +} + +static double +waypt_distance(const waypoint *A, const waypoint *B) /* !!! from A to B !!! */ +{ + double dist = 0; + garmin_fs_p gmsd; + + if ((A == NULL) || (B == NULL)) return 0; + + gmsd = GMSD_FIND(A); + if ((gmsd != NULL) && (gmsd->ilinks != NULL)) + { + garmin_ilink_t *link = gmsd->ilinks; + + dist = distance(A->latitude, A->longitude, link->lat, link->lon); + while (link->next != NULL) + { + garmin_ilink_t *prev = link; + link = link->next; + dist += distance(prev->lat, prev->lon, link->lat, link->lon); + } + dist += distance(link->lat, link->lon, B->latitude, B->longitude); + } else + { + dist = distance(A->latitude, A->longitude, B->latitude, B->longitude); + } + return dist; +} + +static void +convert_datum(waypoint *wpt, const int to_internal_wgs84, double *dest_lat, double *dest_lon) +{ + double alt; + + if (datum_index == 118 /* WGS 84 */) { + if (to_internal_wgs84 == 0) { + *dest_lat = wpt->latitude; + *dest_lon = wpt->longitude; + } + return; + } + + if (to_internal_wgs84) { /* convert the waypoint himself */ + GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, 0.0, + &wpt->latitude, &wpt->longitude, &alt, datum_index); + } else + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + dest_lat, dest_lon, &alt, datum_index); +} + +/* WRITER *****************************************************************/ + +/* Waypoint preparation */ + +static void +enum_waypt_cb(const waypoint *wpt) +{ + garmin_fs_p gmsd; + int wpt_class; + + gmsd = GMSD_FIND(wpt); + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class < 0x80) + { + int i; + + if (gtxt_flags.enum_waypoints) /* enumerate only */ + { + waypoints++; + return; + } + for (i = 0; i < wpt_a_ct; i++) { /* check for duplicates */ + waypoint *tmp = wpt_a[i]; + if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0) + { + wpt_a[i] = (waypoint *)wpt; + waypoints--; + return; + + } + } + wpt_a[wpt_a_ct++] = (waypoint *)wpt; + } + +} + +static int +sort_waypt_cb(const void *a, const void *b) +{ + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return case_ignore_strcmp(wa->shortname, wb->shortname); +} + + +/* common route and track pre-work */ + +static void +prework_hdr_cb(const route_head *rte) +{ + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->length = 0; + cur_info->time = 0; +} + +static void +prework_tlr_cb(const route_head *rte) +{ + cur_info->last_wpt = cur_info->prev_wpt; + route_idx++; +} + +static void +prework_wpt_cb(const waypoint *wpt) +{ + waypoint *prev = cur_info->prev_wpt; + + if (prev != NULL) { + cur_info->time += (wpt->creation_time - prev->creation_time); + cur_info->length += waypt_distance(prev, wpt); + } + else { + cur_info->first_wpt = (waypoint *)wpt; + cur_info->start = wpt->creation_time; + } + cur_info->prev_wpt = (waypoint *)wpt; + cur_info->count++; + routepoints++; +} + + +/* output helpers */ + +static void +print_position(const waypoint *wpt) +{ + int deg; + double min; + char num[64]; + double lat, lon; + + convert_datum((waypoint *)wpt, 0, &lat, &lon); + + deg = fabs(lat); + min = (double)60.0 * (fabs(lat) - deg); + snprintf(num, sizeof(num), "%0*.*f", precision + 3, precision, min); + if (atoi(num) == 60) { + deg++; + min = 0; + } + gbfprintf(fout, "%c%d %0*.*f ", lat < 0.0 ? 'S' : 'N', deg, precision + 3, precision, min); + + deg = fabs(lon); + min = (double)60.0 * (fabs(lon) - deg); + snprintf(num, sizeof(num), "%0*.*f", precision + 3, precision, min); + if (atoi(num) == 60) { + deg++; + min = 0; + } + gbfprintf(fout, "%c%d %0*.*f\t", lon < 0.0 ? 'W' : 'E', deg, precision + 3, precision, min); +} + +static void +print_date_and_time(const time_t time, const int time_only) +{ + struct tm tm; + char tbuf[32]; + + if (time_only) { + tm = *gmtime(&time); + snprintf(tbuf, sizeof(tbuf), "%d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + gbfprintf(fout, "%s", tbuf); + } + else if (time != 0) { + if (gtxt_flags.utc) { + time_t t = time + utc_offs; + tm = *gmtime(&t); + } + else + tm = *localtime(&time); + strftime(tbuf, sizeof(tbuf), date_time_format, &tm); + gbfprintf(fout, "%s ", tbuf); + } + gbfprintf(fout, "\t"); +} + +static void +print_categories(gbuint16 categories) +{ + int i, count; + char *c; + + if (categories == 0) return; + + count = 0; + for (i = 0; i < 16; i++) { + if ((categories & 1) != 0) { + if (global_opts.inifile != NULL) { + char key[3]; + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + } + else c = NULL; + + gbfprintf(fout, "%s", (count++ > 0) ? "," : ""); + if (c == NULL) + gbfprintf(fout, "Category %d", i+1); +// gbfprintf(fout, "%s", gps_categories[i]); + else + gbfprintf(fout, "%s", c); + + } + categories = categories >> 1; + } +} + +static void +print_course(const waypoint *A, const waypoint *B) /* seems to be okay */ +{ + if ((A != NULL) && (B != NULL) && (A != B)) { + int course; + course = si_round((double)360 - course_deg(A->latitude, A->longitude, B->latitude, B->longitude)); + if (course >= 360) { + course -= 360; + } + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "%d%c true", course, 0xB0); + } +} + +static void +print_distance(const double distance, const int no_scale, const int with_tab) +{ + double dist = distance; + + if (gtxt_flags.metric == 0) { + dist = METERS_TO_FEET(dist); + + if ((dist < 5280) || no_scale) + gbfprintf(fout, "%.f ft", dist); + else { + dist = METERS_TO_MILES(distance); + if (dist < (double)100) + gbfprintf(fout, "%.1f mi", dist); + else + gbfprintf(fout, "%d mi", si_round(dist)); + } + } + else + { + if ((dist < 1000) || no_scale) + gbfprintf(fout, "%.f m", dist); + else { + dist = dist / (double)1000.0; + if (dist < (double)100) + gbfprintf(fout, "%.1f km", dist); + else + gbfprintf(fout, "%d km", si_round(dist)); + } + } + if (with_tab) gbfprintf(fout, "\t"); +} + +static void +print_speed(double *distance, time_t *time) +{ + int idist; + double dist = *distance; + char *unit; + + if (!gtxt_flags.metric) { + dist = METERS_TO_MILES(dist) * 1000.0; + unit = "mph"; + } + else unit = "kph"; + idist = si_round(dist); + + if ((*time != 0) && (idist > 0)) { + double speed = dist / (double)*time * SECONDS_PER_HOUR / 1000; + int ispeed = si_round(speed); + + if (speed < (double)0.01) + gbfprintf(fout, "0 %s", unit); + else if (ispeed < 2) + gbfprintf(fout, "%.1f %s", speed, unit); + else + gbfprintf(fout, "%d %s", ispeed, unit); + } + else + gbfprintf(fout, "0 %s", unit); + gbfprintf(fout, "\t"); +} + +static void +print_string(const char *fmt, const char *string) +{ + char *c; + char *buff; + + buff = xstrdup(string); + /* remove unwanted characters from source string */ + for (c = buff; *c; c++) { + if (iscntrl(*c)) { + *c = ' '; + } + } + gbfprintf(fout, fmt, buff); + xfree(buff); +} + + +/* main cb's */ + +static void +write_waypt(const waypoint *wpt) +{ + unsigned char wpt_class; + garmin_fs_p gmsd; + char *wpt_type; + char *dspl_mode; + char *country; + double x; + int i, icon, dynamic; + char *icon_descr; + + gmsd = GMSD_FIND(wpt); + + i = GMSD_GET(display, 0); + if (i > GT_DISPLAY_MODE_MAX) i = 0; + dspl_mode = gt_display_mode_names[i]; + + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class <= gt_waypt_class_map_line) + wpt_type = gt_waypt_class_names[wpt_class]; + else + wpt_type = gt_waypt_class_names[0]; + + gbfprintf(fout, "Waypoint\t%s\t", (wpt->shortname) ? wpt->shortname : ""); + if (wpt_class <= gt_waypt_class_airport_ndb) { + char *temp = wpt->notes; + if (temp == NULL) { + if (wpt->description && (strcmp(wpt->description, wpt->shortname) != 0)) + temp = wpt->description; + else + temp = ""; + } + print_string("%s\t", temp); + } + else + gbfprintf(fout, "\t"); + gbfprintf(fout, "%s\t", wpt_type); + + print_position(wpt); + + if IS_VALID_ALT(wpt->altitude) + print_distance(wpt->altitude, 1, 0); + gbfprintf(fout, "\t"); + + x = GMSD_GET(depth, unknown_alt); + if (x != unknown_alt) + print_distance(x, 1, 0); + gbfprintf(fout, "\t"); + + x = GMSD_GET(proximity, unknown_alt); + if (x != unknown_alt) + print_distance(x, 0, 0); + gbfprintf(fout, "\t"); + + x = GMSD_GET(temperature, unknown_alt); + if (x != unknown_alt) { + if (gtxt_flags.celsius) + gbfprintf(fout, "%.f C", x); + else + gbfprintf(fout, "%.f F", (x * 1.8) + 32); + } + gbfprintf(fout, "\t%s\t", dspl_mode); + + gbfprintf(fout, "Unknown\t"); /* Color is fixed: Unknown */ + + icon = GMSD_GET(icon, -1); + if (icon == -1) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + } + icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + print_string("%s\t", icon_descr); + if (dynamic) xfree(icon_descr); + + print_string("%s\t", GMSD_GET(facility, "")); + print_string("%s\t", GMSD_GET(city, "")); + print_string("%s\t", GMSD_GET(state, "")); + country = gt_get_icao_country(GMSD_GET(cc, "")); + print_string("%s\t", (country != NULL) ? country : ""); + print_date_and_time(wpt->creation_time, 0); + print_string("%s\t", wpt->url ? wpt->url : ""); + print_categories(GMSD_GET(category, 0)); + + gbfprintf(fout, "\r\n"); +} + +static void +route_disp_hdr_cb(const route_head *rte) +{ + current_trk = (route_head *)rte; + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + if (rte->rte_waypt_ct <= 0) return; + + if (!gtxt_flags.route_header_written) { + gtxt_flags.route_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[route_header]); + } + + print_string("\r\nRoute\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_distance(cur_info->length, 0, 1); + print_course(cur_info->first_wpt, cur_info->last_wpt); + gbfprintf(fout, "\t%d waypoints\t", cur_info->count); + print_string("%s\r\n", rte->rte_url ? rte->rte_url : ""); + gbfprintf(fout, "\r\nHeader\t%s\r\n\r\n", headers[rtept_header]); +} + +static void +route_disp_tlr_cb(const route_head *rte) +{ + route_idx++; +} + +static void +route_disp_wpt_cb(const waypoint *wpt) +{ + waypoint *prev = cur_info->prev_wpt; + + gbfprintf(fout, "Route Waypoint\t"); + gbfprintf(fout, "%s\t", wpt->shortname); + + if (prev != NULL) + { + double dist = waypt_distance(prev, wpt); + cur_info->total += dist; + print_distance(cur_info->total, 0, 1); + print_distance(dist, 0, 1); + print_course(prev, wpt); + } + else + print_distance(0, 1, 0); + + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint *)wpt; +} + +static void +track_disp_hdr_cb(const route_head *track) +{ + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + current_trk = (route_head *)track; + if (track->rte_waypt_ct <= 0) return; + + if (!gtxt_flags.track_header_written) { + gtxt_flags.track_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[track_header]); + } + + print_string("\r\nTrack\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_date_and_time(cur_info->start, 0); + print_date_and_time(cur_info->time, 1); + print_distance(cur_info->length, 0, 1); + print_speed(&cur_info->length, &cur_info->time); + print_string("%s", (track->rte_url != NULL) ? track->rte_url : ""); + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n\r\n", headers[trkpt_header]); +} + +static void +track_disp_tlr_cb(const route_head *track) +{ + route_idx++; +} + +static void +track_disp_wpt_cb(const waypoint *wpt) +{ + waypoint *prev = cur_info->prev_wpt; + time_t delta; + double dist; + + gbfprintf(fout, "Trackpoint\t"); + + print_position(wpt); + print_date_and_time(wpt->creation_time, 0); + if IS_VALID_ALT(wpt->altitude) + print_distance(wpt->altitude, 1, 0); + gbfprintf(fout, "\t0.0 %s", (gtxt_flags.metric) ? "m" : "ft"); + if (prev != NULL) { + gbfprintf(fout, "\t"); + delta = wpt->creation_time - prev->creation_time; + dist = distance(prev->latitude, prev->longitude, wpt->latitude, wpt->longitude); + print_distance(dist, 0, 1); + print_date_and_time(delta, 1); + print_speed(&dist, &delta); + print_course(prev, wpt); + } + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint *)wpt; +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +garmin_txt_wr_init(const char *fname) +{ + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fout = gbfopen(fname, "wb", MYNAME); + grid_index = 1; + + gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); + gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); + init_date_and_time_format(); + if (opt_precision) { + precision = atoi(opt_precision); + is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); + } + datum_str = get_option_val(opt_datum, NULL); + datum_index = GPS_Lookup_Datum_Index(datum_str); + is_fatal(datum_index < 0, MYNAME ": Invalid or unknown gps datum (%s)!", datum_str); + + if (opt_utc != NULL) { + if (case_ignore_strcmp(opt_utc, "utc") == 0) + utc_offs = 0; + else + utc_offs = atoi(opt_utc); + utc_offs *= (60 * 60); + gtxt_flags.utc = 1; + } +} + +static void +garmin_txt_wr_deinit(void) +{ + gbfclose(fout); + xfree(date_time_format); +} + +static void +garmin_txt_write(void) +{ + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\tLat/Lon hddd%cmm.mmm'\r\n", 0xB0); + gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); + + waypoints = 0; + gtxt_flags.enum_waypoints = 1; /* enum all waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + gtxt_flags.enum_waypoints = 0; + + if (waypoints > 0) { + int i; + + wpt_a_ct = 0; + wpt_a = (waypoint **)xcalloc(waypoints, sizeof(*wpt_a)); + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + qsort(wpt_a, waypoints, sizeof(*wpt_a), sort_waypt_cb); + + gbfprintf(fout, "Header\t%s\r\n\r\n", headers[waypt_header]); + for (i = 0; i < waypoints; i++) + { + waypoint *wpt = wpt_a[i]; + write_waypt(wpt); + } + xfree(wpt_a); + + route_idx = 0; + route_info = xcalloc(route_count(), sizeof(struct info_s)); + routepoints = 0; + route_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + if (routepoints > 0) + { + route_idx = 0; + route_disp_all(route_disp_hdr_cb, route_disp_tlr_cb, route_disp_wpt_cb); + } + xfree(route_info); + } + + route_idx = 0; + route_info = xcalloc(track_count(), sizeof(struct info_s)); + routepoints = 0; + track_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + + if (routepoints > 0) { + route_idx = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + } + xfree(route_info); +} + +/* READER *****************************************************************/ + +/* helpers */ + +static void +free_header(const header_type ht) +{ + int i; + + for (i = 0; i < MAX_HEADER_FIELDS; i++) { + char *c = header_lines[ht][i]; + if (c != NULL) { + xfree(c); + header_lines[ht][i] = NULL; + } + } + header_ct[ht] = 0; + memset(header_fields[ht], 0, sizeof(header_fields[ht])); +} + +/* data parsers */ + +static void +parse_position(const char *str, waypoint *wpt) +{ + double lat, lon; + unsigned char lathemi, hemilon; + int deg_lat, deg_lon, min_lat, min_lon; + + switch(grid_index) { + case 0: + sscanf(str, "%c%lf %c%lf", &lathemi, &lat, &hemilon, &lon); + break; + case 1: + sscanf(str, "%c%d %lf %c%d %lf", &lathemi, °_lat, &lat, &hemilon, °_lon, &lon); + lat = (double)deg_lat + (lat / (double)60); + lon = (double)deg_lon + (lon / (double)60); + break; + case 2: + sscanf(str, "%c%d %d %lf %c%d %d %lf", &lathemi, °_lat, &min_lat, &lat, &hemilon, °_lon, &min_lon, &lon); + lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); + lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); + break; + } + + if (lathemi == 'S') + wpt->latitude = -lat; + else + wpt->latitude = lat; + + if (hemilon == 'W') + wpt->longitude = -lon; + else + wpt->longitude = lon; +} + +static int +parse_distance(const char *str, double *value) +{ + double x; + char *buff; + + if ((str == NULL) || (*str == '\0')) return 0; + + buff = xmalloc(strlen(str) + 1); + sscanf(str, "%lf %s", &x, buff); + + if (case_ignore_strcmp(buff, "km") == 0) { + *value = x * (double)1000; + } + else if (case_ignore_strcmp(buff, "m") == 0) { /* meters */ + *value = x; + } + else if (case_ignore_strcmp(buff, "ft") == 0) { /* feet */ + *value = FEET_TO_METERS(x); + } + else if (case_ignore_strcmp(buff, "nm") == 0) { /* mile (nautical / geographical) */ + *value = NMILES_TO_METERS(x); + } + else if (case_ignore_strcmp(buff, "mi") == 0) { /* mile (statute) */ + *value = MILES_TO_METERS(x); + } + else if (case_ignore_strcmp(buff, "fa") == 0) { /* fathom */ + *value = FATHOMS_TO_METERS(x); + } + else + fatal(MYNAME ": Unknown distance unit \"%s\" at line %d!\n", str, current_line); + + xfree(buff); + return 1; +} + +static int +parse_date_and_time(char *str, time_t *value) +{ + struct tm tm; + char *cerr, *cin; + + memset(&tm, 0, sizeof(tm)); + cin = lrtrim(str); + if (*cin == '\0') return 0; + + cerr = strptime(cin, date_time_format, &tm); + if (cerr == NULL) { + cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm); + is_fatal(cerr == NULL, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line); + } + +// printf(MYNAME "_parse_date_and_time: %02d.%02d.%04d, %02d:%02d:%02d\n", +// tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec); + + *value = mklocaltime(&tm); + return 1; +} + +static gbuint16 +parse_categories(const char *str) +{ + char buff[256]; + gbuint16 val; + gbuint16 res = 0; + char *cin, *cx; + + if (*str == '\0') return 0; + + strncpy(buff, str, sizeof(buff)); + cin = lrtrim(buff); + if (*cin == '\0') return 0; + + strcat(cin, ","); + + while ((cx = strchr(cin, ','))) { + *cx++ = '\0'; + cin = lrtrim(cin); + if (*cin != '\0') { + if (!garmin_fs_convert_category(cin, &val)) + warning(MYNAME ": Unable to convert category \"%s\" at line %d!", cin, current_line); + else + res = res | val; + } + cin = cx; + } + return res; +} + +static int +parse_temperature(const char *str, double *temperature) +{ + double value; + unsigned char unit; + + if ((str == NULL) || (*str == '\0')) return 0; + + if (sscanf(str, "%lf %c", &value, &unit) == 2) { + unit = toupper(unit); + switch(unit) { + case 'C': *temperature = value; break; + case 'F': *temperature = FAHRENHEIT_TO_CELSIUS(value); break; + default: + fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line); + } + return 1; + } + else + fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line); + return 0; +} + +static void +parse_header(void) +{ + char *str; + int column = -1; + + free_header(unknown_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + header_lines[unknown_header][column] = strupper(xstrdup(str)); + header_ct[unknown_header]++; + if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) break; + } +} + +static int +parse_display(const char *str, int *val) +{ + gt_display_modes_e i; + + if ((str == NULL) || (*str == '\0')) return 0; + + for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) { + if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) { + *val = i; + return 1; + } + } + warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line); + return 0; +} + +static void +bind_fields(const header_type ht) +{ + int i; + char *fields, *c; + + is_fatal((grid_index < 0) || (datum_index < 0), MYNAME ": Incomplete or invalid file header!"); + + if (header_ct[unknown_header] <= 0) return; + free_header(ht); + + /* make a copy of headers[ht], uppercase, replace "\t" with "\0" */ + + i = strlen(headers[ht]); + fields = xmalloc(i + 2); + strcpy(fields, headers[ht]); + strcat(fields, "\t"); + c = strupper(fields); + while ((c = strchr(c, '\t'))) *c++ = '\0'; + + for (i = 0; i < header_ct[unknown_header]; i++) { + char *name; + int field_no; + name = header_lines[ht][i] = header_lines[unknown_header][i]; + header_lines[unknown_header][i] = NULL; + + c = fields; + field_no = 1; + while (c != NULL) { + if (strcmp(c, name) == 0) { + header_fields[ht][i] = field_no; +#if 0 + printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i); +#endif + break; + } + field_no++; + c = c + strlen(c) + 1; + } + } + header_ct[unknown_header] = 0; + xfree(fields); +} + +static void +parse_grid(void) +{ + char *str = csv_lineparse(NULL, "\t", "", 1); + if (str != NULL) { + if (strstr(str, "dd.ddddd") != 0) grid_index = 0; + else if (strstr(str, "mm.mmm") != 0) grid_index = 1; + else if (strstr(str, "mm'ss.s") != 0) grid_index = 2; + else fatal(MYNAME ": Unsupported grid (%s)!\n", str); + } + else + fatal(MYNAME ": Missing grid headline!\n"); +} + +static void +parse_datum(void) +{ + char *str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) { + datum_index = GPS_Lookup_Datum_Index(str); + is_fatal(datum_index < 0, MYNAME ": Unsupported GPS datum \"%s\"!", str); + } + else + fatal(MYNAME ": Missing GPS datum headline!\n"); +} + +static void +parse_waypoint(void) +{ + char *str; + int column = -1; + waypoint *wpt; + garmin_fs_p gmsd = NULL; + + bind_fields(waypt_header); + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) + { + int i, dynamic; + double d; + int field_no = header_fields[waypt_header][column]; + + switch(field_no) { + case 1: wpt->shortname = DUPSTR(str); break; + case 2: wpt->notes = DUPSTR(str); break; + case 3: + for (i = 0; i <= gt_waypt_class_map_line; i++) { + if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) { + GMSD_SET(wpt_class, i); + break; + } + } + break; + case 4: parse_position(str, wpt); break; + case 5: if (parse_distance(str, &d)) wpt->altitude = d; break; + case 6: if (parse_distance(str, &d)) GMSD_SET(depth, d); break; + case 7: if (parse_distance(str, &d)) GMSD_SET(proximity, d); break; + case 8: if (parse_temperature(str, &d)) GMSD_SET(temperature, d); break; + case 9: if (parse_display(str, &i)) GMSD_SET(display, i); break; + case 10: break; /* skip color */ + case 11: + i = gt_find_icon_number_from_desc(str, GDB); + GMSD_SET(icon, i); + wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic); + wpt->wpt_flags.icon_descr_is_dynamic = dynamic; + break; + case 12: GMSD_SETSTR(facility, str); break; + case 13: GMSD_SETSTR(city, str); break; + case 14: GMSD_SETSTR(state, str); break; + case 15: GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname)); break; + case 16: parse_date_and_time(str, &wpt->creation_time); break; + case 17: wpt->url = DUPSTR(str); break; + case 18: GMSD_SET(category, parse_categories(str)); break; + default: break; + } + } + convert_datum(wpt, 1, NULL, NULL); + waypt_add(wpt); +} + +static void +parse_route_header(void) +{ + char *str; + int column = -1; + route_head *rte; + + rte = route_head_alloc(); + + bind_fields(route_header); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[route_header][column]; + switch(field_no) { + case 1: rte->rte_name = DUPSTR(str); break; + case 5: rte->rte_url = DUPSTR(str); break; + } + } + route_add_head(rte); + current_rte = rte; +} + +static void +parse_track_header(void) +{ + char *str; + int column = -1; + route_head *trk; + + bind_fields(track_header); + trk = route_head_alloc(); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[track_header][column]; + switch(field_no) { + case 1: trk->rte_name = DUPSTR(str); break; + case 6: trk->rte_url = DUPSTR(str); break; + } + } + track_add_head(trk); + current_trk = trk; +} + +static void +parse_route_waypoint(void) +{ + char *str; + int column = -1; + waypoint *wpt = NULL; + + bind_fields(rtept_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[rtept_header][column]; + switch(field_no) { + case 1: + is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line); + wpt = find_waypt_by_name(str); + is_fatal((wpt == NULL), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line); + wpt = waypt_dupe(wpt); + break; + } + } + if (wpt != NULL) + route_add_wpt(current_rte, wpt); +} + +static void +parse_track_waypoint(void) +{ + char *str; + int column = -1; + waypoint *wpt; + + bind_fields(trkpt_header); + wpt = waypt_new(); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[trkpt_header][column]; + switch(field_no) { + case 1: parse_position(str, wpt); break; + case 2: parse_date_and_time(str, &wpt->creation_time); break; + case 3: parse_distance(str, &wpt->altitude); break; + } + } + convert_datum(wpt, 1, NULL, NULL); + route_add_wpt(current_trk, wpt); +} + +/***************************************************************/ + +static void +garmin_rd_init(const char *fname) +{ + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fin = gbfopen(fname, "rb", MYNAME); + memset(&header_ct, 0, sizeof(header_ct)); + + datum_index = -1; + grid_index = -1; + + init_date_and_time_format(); +} + +static void +garmin_rd_deinit(void) +{ + header_type h; + + for (h = waypt_header; h <= unknown_header; h++) { + free_header(h); + } + gbfclose(fin); + xfree(date_time_format); +} + +static void +garmin_txt_read(void) +{ + char *buff; + + current_line = 0; + + while ((buff = gbfgetstr(fin))) { + char *cin; + + current_line++; + cin = lrtrim(buff); + if (*cin == '\0') continue; + + cin = csv_lineparse(cin, "\t", "", 0); + + if (cin == NULL) continue; + else if (case_ignore_strcmp(cin, "Header") == 0) parse_header(); + else if (case_ignore_strcmp(cin, "Grid") == 0) parse_grid(); + else if (case_ignore_strcmp(cin, "Datum") == 0) parse_datum(); + else if (case_ignore_strcmp(cin, "Waypoint") == 0) parse_waypoint(); + else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) parse_route_waypoint(); + else if (case_ignore_strcmp(cin, "Trackpoint") == 0) parse_track_waypoint(); + else if (case_ignore_strcmp(cin, "Route") == 0) parse_route_header(); + else if (case_ignore_strcmp(cin, "Track") == 0) parse_track_header(); + else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ; + else + fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line); + + /* flush pending data */ + while (csv_lineparse(NULL, "\t", "", 0)); + } +} + +ff_vecs_t garmin_txt_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + garmin_rd_init, + garmin_txt_wr_init, + garmin_rd_deinit, + garmin_txt_wr_deinit, + garmin_txt_read, + garmin_txt_write, + NULL, + garmin_txt_args, + CET_CHARSET_MS_ANSI, 0 +}; + +#endif // CSVFMTS_ENABLED diff --git a/gbfile.c b/gbfile.c new file mode 100644 index 000000000..bc5505550 --- /dev/null +++ b/gbfile.c @@ -0,0 +1,667 @@ +/* + + Common GPSBabel file I/O API + + Copyright (C) 2006 Olaf Klein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbfile.h" + +#include +#include +#include +#include +#include + + +#if __WIN32__ +/* taken from minigzip.c (part of the zlib project) */ +# include +# include +# define SET_BINARY_MODE(file) _setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define MYNAME "gbfile" +#define NO_ZLIB MYNAME ": No zlib support\n." + +/* About the ZLIB_INHIBITED stuff: + * + * If a user goes out of his way to build with ZLIB_INHIBITED set, + * we jettison our use of zlib entirely within this file, replacing + * all calls out to zlib with calls to abort() as that's an internal + * consistency error. + * + */ + +/* GPSBabel 'file' standard calls */ + +gbfile * +gbfopen(const char *filename, const char *mode, const char *module) +{ + gbfile *file; + const char *m; + int len; + + file = xcalloc(1, sizeof(*file)); + + file->name = xstrdup(filename); + file->module = xstrdup(module); + file->line = xstrdup(""); + file->mode = 'r'; // default + file->binary = (strchr(mode, 'b') != NULL); + + for (m = mode; *m; m++) { + switch(tolower(*m)) { + case 'r': + file->mode = 'r'; +#if !ZLIB_INHIBITED + file->gzapi = 1; /* native or transparent */ +#endif + break; + case 'w': + file->mode = 'w'; + break; + } + } + + /* Do we have a '.gz' extension in the filename ? */ + len = strlen(file->name); + if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { + /* force gzipped files on output */ + file->gzapi = 1; + } + + if (file->gzapi) { +#if !ZLIB_INHIBITED + char openmode[32]; + + /* under non-posix systems files MUST be opened in binary mode */ + + strcpy(openmode, mode); + if (strchr(mode, 'b') == NULL) + strncat(openmode, "b", sizeof(openmode)); + + if (strcmp(filename, "-") == 0) { + FILE *fd; + if (file->mode == 'r') + fd = stdin; + else + fd = stdout; + SET_BINARY_MODE(fd); + file->handle.gz = gzdopen(fileno(fd), openmode); + } + else + file->handle.gz = gzopen(filename, openmode); + + if (file->handle.gz == NULL) { + fatal("%s: Cannot %s file '%s'!\n", + module, + (file->mode == 'r') ? "open" : "create", + filename); + } + file->gzapi = 1; +#else + /* This is the only runtime test we make */ + fatal("%s: Zlib was not included in this build.\n", file->module); +#endif + } + else { + file->handle.std = xfopen(filename, mode, module); + } +#ifdef DEBUG_MEM + file->buffsz = 1; +#else + file->buffsz = 256; +#endif + file->buff = xmalloc(file->buffsz); + + return file; +} + +/* + * gbfopen_be: as gbfopen, but set the BIG-ENDIAN flag + */ + +gbfile * +gbfopen_be(const char *filename, const char *mode, const char *module) +{ + gbfile *result; + + result = gbfopen(filename, mode, module); + result->big_endian = 1; + + return result; +} + +void +gbfclose(gbfile *file) +{ + if (!file) return; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + gzclose(file->handle.gz); +#else + fatal(NO_ZLIB); +#endif + } + else { + fclose(file->handle.std); + } + xfree(file->name); + xfree(file->module); + xfree(file->line); + xfree(file->buff); + xfree(file); +} + +int +gbfgetc(gbfile *file) +{ + unsigned char c; + + /* errors are caught in gbfread */ + if (gbfread(&c, 1, 1, file) == 0) { + return EOF; + } + else { + return (unsigned int)c; + } +} + +char * +gbfgets(char *buf, int len, gbfile *file) +{ + char *result = buf; + + while (--len > 0) { + int c = gbfgetc(file); + + if (c == EOF) break; + + *(unsigned char *)buf = (unsigned char)c; + buf++; + + if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) gbfungetc(c, file); + break; + } + else if (c == '\n') + break; + } + *buf = '\0'; + return (*result != '\0') ? result : NULL; +} + + +gbsize_t +gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +{ + if ((size == 0) || (members == 0)) return 0; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + int result; + result = gzread(file->handle.gz, buf, size * members) / size; + + if ((result < 0) || ((gbsize_t)result < members)) { + int errnum; + const char *errtxt; + + errtxt = gzerror(file->handle.gz, &errnum); + if ((errnum != Z_STREAM_END) && (errnum != 0)) + fatal("%s: zlib returned error %d ('%s')!\n", + file->module, errnum, errtxt); + } + return (gbsize_t) result; +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + int errno; + gbsize_t result = fread(buf, size, members, file->handle.std); + + if ((result < members) && (errno = ferror(file->handle.std))) { + fatal("%s: Error %d occured during read of file '%s'!\n", + file->module, errno, file->name); + } + return result; + } +} + +int +gbfprintf(gbfile *file, const char *format, ...) +{ + int len; + + for (;;) { + va_list args; + + va_start(args, format); + len = vsnprintf(file->buff, file->buffsz, format, args); + va_end(args); + + /* Unambiguous Success */ + if ((len > -1) && (len < file->buffsz)) + break; + + /* First case: C99 behaviour. Len is correctly sized. + * add space for null terminator. Next time through the + * loop we're guaranteed success. + * + * Second case: SUS (and Windows) behaviour. We know it + * doesn't fit, but we don't know how big it has to be. +` * double it and try again. We'll loop until we succeed. + * + * Since we keep the I/O buffer in the file handle, we + * quickly reach a steady state on the size of these buffers. + */ + if (len > -1) + file->buffsz = len + 1; + else + file->buffsz *= 2; + + file->buff = xrealloc(file->buff, file->buffsz); + } + return gbfwrite(file->buff, 1, len, file); +} + +int +gbfputc(int c, gbfile *file) +{ + unsigned char temp = (unsigned int) c; + + gbfwrite(&temp, 1, 1, file); + + return c; +} + +int +gbfputs(const char *s, gbfile *file) +{ + return gbfwrite(s, 1, strlen(s), file); +} + +int +gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) +{ + int result; + + if ((size == 0) || (members == 0)) return 0; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + result = gzwrite(file->handle.gz, buf, size * members) / size; +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + result = fwrite(buf, size, members, file->handle.std); + } + + if (result != members) { + fatal("%s: Could not write %u bytes to %s!\n", + file->module, + (members - result) * size, + file->name); + } + + return result; +} + +int +gbfflush(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + return gzflush(file->handle.gz, Z_SYNC_FLUSH); +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + return fflush(file->handle.std); + } +} + +void +gbfclearerr(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + gzclearerr(file->handle.gz); +#endif + } + else { + clearerr(file->handle.std); + } +} + +int +gbferror(gbfile *file) +{ + int errnum; + + if (file->gzapi) { +#if !ZLIB_INHIBITED + (void)gzerror(file->handle.gz, &errnum); +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + errnum = ferror(file->handle.std); + } + return errnum; +} + +void +gbfrewind(gbfile *file) +{ + (void)gbfseek(file, 0, SEEK_SET); + gbfclearerr(file); +} + +int +gbfseek(gbfile *file, gbint32 offset, int whence) +{ + + if (file->gzapi) { + int result; + + assert(whence != SEEK_END); + +#if !ZLIB_INHIBITED + result = gzseek(file->handle.gz, offset, whence); +#else + result = 1; +#endif + is_fatal(result < 0, + "%s: online compression not yet supported for this format!", file->module); + return 0; + + } + else { + return fseek(file->handle.std, offset, whence); + } +} + +gbsize_t +gbftell(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + return gztell(file->handle.gz); +#else + fatal(NO_ZLIB); + return -1; +#endif + } + else { + return ftell(file->handle.std); + } +} + +int +gbfeof(gbfile *file) +{ + if (file->gzapi) { +#if !ZLIB_INHIBITED + return gzeof(file->handle.gz); +#else + fatal(NO_ZLIB); + return 0; +#endif + } + else { + return feof(file->handle.std); + } +} + +int +gbfungetc(const int c, gbfile *file) +{ + int r = -1; + if (file->gzapi) { +#if !ZLIB_INHIBITED + r = gzungetc(c, file->handle.gz); +#else + fatal(NO_ZLIB); +#endif + } + else { + r = ungetc(c, file->handle.std); + } + return r; +} + +/* GPSBabel 'file' enhancements */ + +gbint32 +gbfgetint32(gbfile *file) +{ + char buf[4]; + + gbfread(buf, 1, sizeof(buf), file); + + if (file->big_endian) + return be_read32(buf); + else + return le_read32(buf); +} + +gbint16 +gbfgetint16(gbfile *file) +{ + char buf[2]; + + gbfread(buf, 1, sizeof(buf), file); + + if (file->big_endian) + return be_read16(buf); + else + return le_read16(buf); +} + +double +gbfgetdbl(gbfile *file) +{ + char buf[8]; + gbfread(buf, 1, sizeof(buf), file); + return le_read_double(buf); +} + +float +gbfgetflt(gbfile *file) +{ + union { + float f; + gbint32 i; + } x; + + x.i = gbfgetint32(file); + return x.f; +} + +/* + * gbfgetcstr: Reads a string from file until either a '\0' or eof. + * The result is a temporary allocated entity: use it or free it! + */ +char * +gbfgetcstr(gbfile *file) +{ + int len, size; + char *result; + + len = size = 0; + result = xstrdup(""); + + while (1) { + char c = gbfgetc(file); + + if ((c == 0) || (c == EOF)) break; + + if (len == size) { + size += 32; + result = xrealloc(result, size + 1); + } + result[len] = c; + len++; + } + + if ((len + 1) != size) + result = xrealloc(result, len + 1); + + return result; +} + +/* + * gbfgetpstr: Reads a pascal string (first byte is length) from file. + * The result is a temporary allocated entity: use it or free it! + */ +char * +gbfgetpstr(gbfile *file) +{ + int len; + char *result; + + len = gbfgetc(file); + result = xmalloc(len + 1); + + if (len > 0) + gbfread(result, 1, len, file); + result[len] = '\0'; + + return result; +} + +/* + * gbfgetstr: Reads a string from file (util any type of line-breaks or eof or error) + * except xfree and free you can do all possible things with the result + */ +char * +gbfgetstr(gbfile *file) +{ + int len; + char *result = file->line; + + len = file->linesz = 0; + + while (1) { + char c = gbfgetc(file); + + if ((c == EOF) || (c == 0x1A)) { + if (len == 0) { + return NULL; + } + break; + } + else if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) gbfungetc(c, file); + break; + } + else if (c == '\n') { + break; + } + if (len == file->linesz) { + file->linesz = len + 128; + result = file->line = xrealloc(file->line, len + 128 + 1); + } + result[len] = c; + len++; + } + result[len] = '\0'; // terminate resulting string + + return result; +} + +int +gbfputint16(const gbint16 i, gbfile *file) +{ + char buf[2]; + + if (file->big_endian) + be_write16(buf, i); + else + le_write16(buf, i); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +int +gbfputint32(const gbint32 i, gbfile *file) +{ + char buf[4]; + + if (file->big_endian) + be_write32(buf, i); + else + le_write32(buf, i); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +int +gbfputdbl(const double d, gbfile *file) +{ + char buf[8]; + le_write_double(buf, d ); + return gbfwrite(buf, 1, sizeof(buf), file); +} + +int +gbfputflt(const float f, gbfile *file) +{ + union { + float f; + gbint32 i; } x; + + x.f = f; + return gbfputint32(x.i, file); +} + +int +gbfputcstr(const char *s, gbfile *file) +{ + return gbfwrite(s, 1, strlen(s) + 1, file); +} + +int +gbfputpstr(const char *s, gbfile *file) +{ + int len; + + len = strlen(s); + if (len > 255) + len = 255; + gbfputc(len, file); + gbfwrite(s, 1, len, file); + + return len + 1; +} + +/* Thats all, sorry */ diff --git a/gbfile.h b/gbfile.h new file mode 100644 index 000000000..596e9c2c5 --- /dev/null +++ b/gbfile.h @@ -0,0 +1,95 @@ +/* + + Common GPSBabel file I/O API + + Copyright (C) 2006 Olaf Klein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef GBFILE_H +#define GBFILE_H + +#include "config.h" +#include "defs.h" +#include + +typedef struct gbfile_s { +#ifdef DEBUG_MEM + void *dummy; /* ZERO pointer for stdio oop's */ +#endif + union { + FILE *std; +#if !ZLIB_INHIBITED + gzFile *gz; +#endif + } handle; + char *name; + char *module; + char *line; + int linesz; + char *buff; /* static growing buffer, primary used by gbprintf */ + int buffsz; + char mode; + unsigned char big_endian:1; + unsigned char binary:1; + unsigned char gzapi:1; +} gbfile; + + +gbfile *gbfopen(const char *filename, const char *mode, const char *module); +gbfile *gbfopen_be(const char *filename, const char *mode, const char *module); +#define gbfopen_le gbfopen +void gbfclose(gbfile *file); + +gbsize_t gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); +int gbfgetc(gbfile *file); +char *gbfgets(char *buf, int len, gbfile *file); + +int gbfprintf(gbfile *file, const char *format, ...); +int gbfputc(int c, gbfile *file); +int gbfputs(const char *s, gbfile *file); +int gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file); +int gbfflush(gbfile *file); + +void gbfclearerr(gbfile *file); +int gbferror(gbfile *file); +void gbfrewind(gbfile *file); +int gbfseek(gbfile *file, gbint32 offset, int whence); +gbsize_t gbftell(gbfile *file); +int gbfeof(gbfile *file); +int gbfungetc(const int c, gbfile *file); + +gbint32 gbfgetint32(gbfile *file); +#define gbfgetuint32 (gbuint32)gbfgetint32 +gbint16 gbfgetint16(gbfile *file); +#define gbfgetuint16 (gbuint16)gbfgetint16 +double gbfgetdbl(gbfile *file); // read a double value +float gbfgetflt(gbfile *file); // read a float value +char *gbfgetstr(gbfile *file); // read until any type of line-breaks or EOF +char *gbfgetpstr(gbfile *file); // read a pascal string + +int gbfputint16(const gbint16 i, gbfile *file); +#define gbfputuint16(a,b) gbfputint16((gbuint16)(a),(b)) +int gbfputint32(const gbint32 i, gbfile *file); +#define gbfputuint32(a,b) gbfputint32((gbuint32)(a),(b)) + +int gbfputdbl(const double d, gbfile *file); // write a double value +int gbfputflt(const float f, gbfile *file); // write a float value +int gbfputcstr(const char *s, gbfile *file); // write string including '\0' +int gbfputpstr(const char *s, gbfile *file); // write as pascal string + +#endif diff --git a/gbser.c b/gbser.c new file mode 100644 index 000000000..0daff0d79 --- /dev/null +++ b/gbser.c @@ -0,0 +1,181 @@ +/* + Serial interface + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbser_private.h" + +#include +#include + +void gbser__db(int l, const char *msg, ...) { + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); +} + +/* Set the serial port speed. + */ +int gbser_set_speed(void *handle, unsigned speed) { + return gbser_set_port(handle, speed, 8, 0, 1); +} + +static int parity_letter(char c) { + switch (c) { + case 'N': case 'n': + return 0; + case 'O': case 'o': + return 1; + case 'E': case 'e': + return 2; + default: + return -1; + } +} + +/* Set the serial port up by parsing the supplied parameter string. + * Valid parameter strings look like '4800,8,N,1'. Parsing is case- + * insensitive, spaces are allowed around the commas and omitted + * trailing fields will default to '8', 'N' and '1' + */ +int gbser_setup(void *handle, const char *spec) { + unsigned arg[] = { 4800, 8, 0, 1 }; + int ap; + + for (ap = 0; ap < sizeof(arg) / sizeof(arg[0]); ap++) { + unsigned t = 0; + int pl; + while (isspace(*spec)) { spec++; } + /* Allow 'N', 'O' or 'E' as the parity spec */ + if (ap == 2 && (pl = parity_letter(*spec), pl >= 0)) { + t = pl; + spec++; + } else { + if (!isdigit(*spec)) { break; } + while (isdigit(*spec)) { t = t * 10 + *spec++ - '0'; } + } + arg[ap] = t; + while (isspace(*spec)) { spec++; } + if (*spec != ',') { break; } + spec++; + } + + if (*spec != '\0') { + return gbser_ERROR; + } + + return gbser_set_port(handle, arg[0], arg[1], arg[2], arg[3]); +} + +/* Return true if there are characters available on the serial port + */ +int gbser_avail(void *handle) { + return gbser__fill_buffer(handle, 1, NULL); +} + +/* Read as many bytes as are available without blocking. At most |len| + * bytes will be read. Returns the number of bytes read or gbser_ERROR if an + * error occurs. + */ +int gbser_read(void *handle, void *buf, unsigned len) { + int got = 0; + + while (len > 0) { + int rc = gbser__fill_buffer(handle, len, NULL); + if (rc < 0) { + /* error */ + return rc; + } else if (rc == 0) { + /* nothing available */ + break; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; +} + +/* Read the specified number of bytes. Block until the requested number + * of bytes have been read or the timeout (in ms) is exceeded. + */ +int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms) { + int got = 0; + + while (len > 0 && ms != 0) { + int rc; + if (rc = gbser__fill_buffer(handle, len, &ms), rc < 0) { + return rc; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; +} + +/* Read a single character from the port, returning immediately if + * none are available. + */ +int gbser_readc(void *handle) { + char buf; + int rc; + + rc = gbser_read(handle, &buf, 1); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } +} + +/* Read a single character from the port, waiting up to |ms| + * milliseconds for a character to be available. + */ +int gbser_readc_wait(void *handle, unsigned ms) { + char buf; + int rc; + + rc = gbser_read_wait(handle, &buf, 1, ms); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } +} + +/* Write a null terminated string in |str| to the serial + * port. + */ +int gbser_print(void *handle, const char *str) { + return gbser_write(handle, str, (unsigned) strlen(str)); +} + +/* Write a single character to the serial port. + */ +int gbser_writec(void *handle, int c) { + return gbser_write(handle, &c, 1); +} diff --git a/gbser.h b/gbser.h new file mode 100644 index 000000000..550c5313d --- /dev/null +++ b/gbser.h @@ -0,0 +1,137 @@ +/* + OS Abstraction for serial interface. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifndef __GBSER_H +#define __GBSER_H + +#define gbser_OK 0 +#define gbser_NOTHING -1 +#define gbser_TIMEOUT -2 +#define gbser_ERROR -3 + +#if defined(__WIN32__) || defined(__CYGWIN__) +#define WINSERIAL 1 +#else +#define POSIXSERIAL 1 +#endif + +/* Open a serial port. |port_name| is the (platform specific) name + * of the serial device to open. Under WIN32 familiar DOS port names + * ('com1:') are translated into the equivalent name required by + * WIN32 + */ +void *gbser_init(const char *port_name); + +/* Close a serial port + */ +void gbser_deinit(void *handle); + +/* Set the serial port speed. + */ +int gbser_set_speed(void *handle, unsigned speed); + +/* Set the serial port speed, start, parity and stop bits */ +int gbser_set_port(void *handle, unsigned speed, + unsigned bits, + unsigned parity, + unsigned stop); + +/* Set the serial port up by parsing the supplied parameter string. + * Valid parameter strings look like '4800,8,N,1'. Parsing is case- + * insensitive, spaces are allowed around the commas and omitted + * trailing fields will default to '8', 'N' and '1' + */ +int gbser_setup(void *handle, const char *spec); + +/* Return true if there are characters available on the serial port + */ +int gbser_avail(void *handle); + +/* Read as many bytes as are available without blocking. At most |len| + * bytes will be read. Returns the number of bytes read or gbser_ERROR if an + * error occurs. + */ +int gbser_read(void *handle, void *buf, unsigned len); + +/* Read the specified number of bytes. Block until the requested number + * of bytes have been read or the timeout (in ms) is exceeded. + */ +int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms); + +/* Read from the serial port until the specified |eol| character is + * found. Any character matching |discard| will be discarded. To + * read lines terminated by 0x0A0x0D discarding linefeeds use + * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); + */ +int gbser_read_line(void *handle, void *buf, + unsigned len, unsigned ms, + int eol, int discard); + +/* Read a single character from the port, returning immediately if + * none are available. TODO: Define return values + */ +int gbser_readc(void *handle); + +/* Read a single character from the port, waiting up to |ms| + * milliseconds for a character to be available. + */ +int gbser_readc_wait(void *handle, unsigned ms); + +/* Discard any pending input on the serial port. + */ +int gbser_flush(void *handle); + +/* Write |len| bytes from |buf| to the serial port. + */ +int gbser_write(void *handle, const void *buf, unsigned len); + +/* Write a null terminated string in |str| to the serial + * port. + */ +int gbser_print(void *handle, const char *str); + +/* Write a single character to the serial port. + */ +int gbset_writec(void *handle, int c); + +/* Return true if a port name seems to refer to a serial port. + * On Windows this tests the filename (against the regex + * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of + * isatty() + */ +int gbser_is_serial(const char *port_name); + +/* This isn't part of the above abstraction; it's just a helper for + * the other serial modules in the tree. + * + * Windows does a weird thing with serial ports. + * COM ports 1 - 9 are "COM1:" through "COM9:" + * The one after that is \\.\\com10 - this function tries to plaster over + * that. + * It returns a pointer to a staticly allocated buffer and is therefore not + * thread safe. The buffer pointed to remains valid only until the next + * call to this function. + */ + +const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len); +const char *fix_win_serial_name(const char *comname); + +#endif /* GBSER_H */ diff --git a/gbser_posix.c b/gbser_posix.c new file mode 100644 index 000000000..6e398c13f --- /dev/null +++ b/gbser_posix.c @@ -0,0 +1,424 @@ +/* + Serial interface for POSIX tty handling. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbser_private.h" + +#include +#include +#include +#include +#include + +#include +#include + +typedef struct { + struct termios old_tio; + struct termios new_tio; + int fd; + unsigned vmin, vtime; + unsigned long magic; + + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; +} gbser_handle; + +/* Wrapper to safely cast a void * into a gbser_handle */ +static gbser_handle *gbser__get_handle(void *p) { + gbser_handle *h = (gbser_handle *) p; + assert(h->magic == MYMAGIC); + return h; +} + +static speed_t mkspeed(unsigned br) { + switch (br) { + case 1200: return B1200; + case 2400: return B2400; + case 4800: return B4800; + case 9600: return B9600; + case 19200: return B19200; +#if defined B57600 + case 57600: return B57600; +#endif +#if defined B115200 + case 115200: return B115200; +#endif + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } +} + +typedef struct timeval hp_time; + +static void get_time(hp_time *tv) { + gettimeofday(tv, NULL); +} + +static double elapsed(hp_time *tv) { + hp_time now; + double ot = (double) tv->tv_sec * 1000 + + (double) tv->tv_usec / 1000; + double nt; + gettimeofday(&now, NULL); + nt = (double) now.tv_sec * 1000 + + (double) now.tv_usec / 1000; + /*printf("elapsed -> %f\n", nt - ot);*/ + return nt - ot; +} + +static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) { + if (vmin > 255) { vmin = 255; } + if (vtime > 255) { vtime = 255; } + if (vmin != h->vmin || vtime != h->vtime) { + h->vmin = h->new_tio.c_cc[VMIN] = vmin; + h->vtime = h->new_tio.c_cc[VTIME] = vtime; + + /*printf("VMIN=%d, VTIME=%d\n", h->vmin, h->vtime);*/ + + return tcsetattr(h->fd, TCSANOW, &h->new_tio) ? gbser_ERROR : gbser_OK; + } else { + return 0; + } +} + +/* Open a serial port. |port_name| is the (platform specific) name + * of the serial device to open. Under WIN32 familiar DOS port names + * ('com1:') are translated into the equivalent name required by + * WIN32 + */ +void *gbser_init(const char *port_name) { + gbser_handle *h; + + gbser__db(4, "gbser_init(\"%s\")\n", port_name); + + h = xcalloc(sizeof *h, 1); + h->magic = MYMAGIC; + h->vmin = h->vtime = 0; + + if (h->fd = open(port_name, O_RDWR | O_NOCTTY), h->fd == -1) { + gbser__db(1, "Failed to open port (%s)\n", strerror(errno)); + goto failed; + } + + if (!isatty(h->fd)) { + gbser__db(1, "%s is not a TTY\n"); + goto failed; + } + + if (gbser_set_port(h, 4800, 8, 0, 1)) { + gbser__db(1, "gbser_set_port() failed\n"); + goto failed; + } + + return h; + +failed: + if (h->fd != -1) { + close(h->fd); + } + + xfree(h); + + return NULL; +} + +/* Close a serial port + */ +void gbser_deinit(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + + tcsetattr(h->fd, TCSAFLUSH, &h->old_tio); + close(h->fd); + + xfree(h); +} + +int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { + gbser_handle *h = gbser__get_handle(handle); + speed_t s; + + static unsigned bit_flags[] = { + 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 + }; + + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } + + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } + + s = mkspeed(speed); + + /* TODO: We don't /fully/ initialise the port's stat here... */ + + tcgetattr(h->fd, &h->old_tio); + + h->new_tio = h->old_tio; + + /* clear bits */ +// cfmakeraw(&h->new_tio); + h->new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + h->new_tio.c_oflag &= ~OPOST; + h->new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + h->new_tio.c_cflag &= ~(CSIZE|PARENB); + h->new_tio.c_cflag |= CS8; + + h->new_tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | + INLCR | IGNCR | IXON); + h->new_tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); + + /* set data bits, */ + h->new_tio.c_cflag |= bit_flags[bits]; + + /* stop bits and... */ + if (stop == 2) { + h->new_tio.c_cflag |= CSTOPB; + } + + /* parity */ + if (parity != 0) { + h->new_tio.c_cflag |= PARENB; + if (parity == 1) { + h->new_tio.c_cflag |= PARODD; + } + } + + h->new_tio.c_oflag = 0; + h->new_tio.c_lflag = 0; + + h->new_tio.c_cc[VMIN] = h->vmin; + h->new_tio.c_cc[VTIME] = h->vtime; + + cfsetospeed(&h->new_tio, s); + cfsetispeed(&h->new_tio, s); + + return tcsetattr(h->fd, TCSADRAIN, &h->new_tio) ? gbser_ERROR : gbser_OK; +} + +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { + gbser_handle *h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char *cp = *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void *) cp; + return count; +} + +/* Return when the input buffer contains at least |want| bytes or |*ms| + * milliseconds have elapsed. |ms| may be NULL or |*ms| may be zero to + * poll the port for available bytes and return immediately. |*ms| will + * be updated to indicate the remaining time on exit. + * Returns the number of bytes available (>=0) or an error code (<0). + */ +int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { + int rc; + gbser_handle *h = gbser__get_handle(handle); + + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } + + if (NULL == ms || 0 == *ms) { + if ((rc = set_rx_timeout(h, 0, 0), rc < 0) || + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; + } + h->inbuf_used += rc; + /*printf("Got %d bytes\n", rc);*/ + } else { + double time_left = *ms; + hp_time tv; + get_time(&tv); + + for (;;) { + fd_set rec; + struct timeval t; + + time_left = *ms - elapsed(&tv); + if (time_left <= 0 || h->inbuf_used >= want) { + break; + } + + FD_ZERO(&rec); + FD_SET(h->fd, &rec); + + t.tv_sec = (time_t) time_left / 1000; + t.tv_usec = ((unsigned) time_left % 1000) * 1000; + + if (select(h->fd + 1, &rec, NULL, NULL, &t) < 0) { + return gbser_ERROR; + } + + time_left = *ms - elapsed(&tv); + + if (FD_ISSET(h->fd, &rec)) { + unsigned vmin = 0, vtime = 0; + if (time_left >= 100) { + vmin = want - h->inbuf_used; + vtime = (unsigned) time_left / 100; + } + if ((rc = set_rx_timeout(h, vmin, vtime), rc < 0) || + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; + } + h->inbuf_used += rc; + /*printf("Got %d bytes\n", rc);*/ + } + } + *ms = (time_left < 0) ? 0 : time_left; + } + + return h->inbuf_used; +} + +/* Discard any pending input on the serial port. + */ +int gbser_flush(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (tcflush(h->fd, TCIFLUSH)) { + return gbser_ERROR; + } + + return gbser_OK; +} + +/* Write |len| bytes from |buf| to the serial port. + */ +int gbser_write(void *handle, const void *buf, unsigned len) { + gbser_handle *h = gbser__get_handle(handle); + const char *bp = buf; + int rc; + while (len > 0) { + /*printf("write(%d, %p, %d)\n", h->fd, bp, len);*/ + if (rc = write(h->fd, bp, len), rc < 0) { + printf("rc = %d, errno = %d (%s)\n", rc, errno, strerror(errno)); + return gbser_ERROR; + } + len -= rc; + bp += rc; + } + return gbser_OK; +} + +/* Return true if a port name seems to refer to a serial port. + * On Windows this tests the filename (against the regex + * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of + * isatty() + */ + +int gbser_is_serial(const char *port_name) { + int fd; + int is_port = 0; + + if (fd = open(port_name, O_RDWR | O_NOCTTY), fd == -1) { + gbser__db(1, "Failed to open port (%s) to check its type\n", strerror(errno)); + return 0; + } + + is_port = isatty(fd); + + close(fd); + + return is_port; +} + +/* This isn't part of the above abstraction; it's just a helper for + * the other serial modules in the tree. + * + * Windows does a weird thing with serial ports. + * COM ports 1 - 9 are "COM1:" through "COM9:" + * The one after that is \\.\\com10 - this function tries to plaster over + * that. + * It returns a pointer to a staticly allocated buffer and is therefore not + * thread safe. The buffer pointed to remains valid only until the next + * call to this function. + */ + +const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len) { + strncpy(obuf, comname, len); + return obuf; +} + +static char gb_com_buffer[100]; + +const char *fix_win_serial_name(const char *comname) { + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); +} + +/* Read from the serial port until the specified |eol| character is + * found. Any character matching |discard| will be discarded. To + * read lines terminated by 0x0A0x0D discarding linefeeds use + * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); + */ +int gbser_read_line(void *handle, void *buf, + unsigned len, unsigned ms, + int eol, int discard) { + char *bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; + } + } +} diff --git a/gbser_private.h b/gbser_private.h new file mode 100644 index 000000000..318455e80 --- /dev/null +++ b/gbser_private.h @@ -0,0 +1,27 @@ +/* + Serial interface - private header for gbser*.c + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#define MYMAGIC 0x91827364 +#define BUFSIZE 512 + +void gbser__db(int l, const char *msg, ...); +int gbser__fill_buffer(void *h, unsigned want, unsigned *ms); +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len); diff --git a/gbser_win.c b/gbser_win.c new file mode 100644 index 000000000..145969e36 --- /dev/null +++ b/gbser_win.c @@ -0,0 +1,429 @@ +/* + Serial interface - Windows layer. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "gbser.h" +#include "gbser_private.h" + +#include +#include + +#include +#include + +typedef struct { + HANDLE comport; + DWORD timeout; + unsigned long magic; + + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; +} gbser_handle; + +#define DEV_PREFIX "\\\\.\\\\" + +/* Wrapper to safely cast a void * into a gbser_handle */ +static gbser_handle *gbser__get_handle(void *p) { + gbser_handle *h = (gbser_handle *) p; + assert(h->magic == MYMAGIC); + return h; +} + +static DWORD mkspeed(unsigned br) { + switch (br) { + case 1200: return CBR_1200; + case 2400: return CBR_2400; + case 4800: return CBR_4800; + case 9600: return CBR_9600; + case 19200: return CBR_19200; + case 57600: return CBR_57600; + case 115200: return CBR_115200; + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } +} + +typedef LARGE_INTEGER hp_time; + +static void get_time(hp_time *tv) { + QueryPerformanceCounter(tv); +} + +static double elapsed(hp_time *tv) { + hp_time now; + LARGE_INTEGER tps; + + QueryPerformanceFrequency(&tps); + QueryPerformanceCounter(&now); + + return ((double) (now.QuadPart - tv->QuadPart) / + (double) tps.QuadPart) * 1000; +} + +static int set_rx_timeout(gbser_handle *h, DWORD timeout) { + if (timeout != h->timeout) { + COMMTIMEOUTS to; + + if (!GetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; + } + + to.ReadIntervalTimeout = timeout; + to.ReadTotalTimeoutMultiplier = 0; + to.ReadTotalTimeoutConstant = timeout; + to.WriteTotalTimeoutMultiplier = 0; + to.WriteTotalTimeoutConstant = 0; + + if (!SetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; + } else { + h->timeout = timeout; + return gbser_OK; + } + } else { + return gbser_OK; + } +} + +/* This isn't part of the above abstraction; it's just a helper for + * the other serial modules in the tree. + * + * Windows does a weird thing with serial ports. + * COM ports 1 - 9 are "COM1:" through "COM9:" + * The one after that is \\.\\com10 - this function tries to plaster over + * that. + * + * Worse still, Win98 and ME fail the open if you rename com1 to be \\.\\com1: + * + * It returns a pointer to a staticly allocated buffer and is therefore not + * thread safe. The buffer pointed to remains valid only until the next + * call to this function. + */ + +const char * +fix_win_serial_name_r(const char *comname, char *obuf, size_t len) +{ + if (!gbser_is_serial(comname) || + ((strlen(comname) == 5) && (comname[4] == ':')) || + ((strlen(comname) == 4) && (case_ignore_strncmp(comname, "com", 3) == 0)) + ) { + strncpy(obuf, comname, len); + } else { + size_t l; + snprintf(obuf, len, DEV_PREFIX "%s", comname); + l = strlen(obuf); + if (obuf[l - 1] == ':') { + obuf[l - 1] = '\0'; + } + } + + return obuf; +} + +static char gb_com_buffer[100]; + +const char *fix_win_serial_name(const char *comname) +{ + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); +} + +/* Open a serial port. |port_name| is the (platform specific) name + * of the serial device to open. Under WIN32 familiar DOS port names + * ('com1:') are translated into the equivalent name required by + * WIN32 + */ +void *gbser_init(const char *port_name) +{ + HANDLE comport; + gbser_handle* h = xcalloc(1, sizeof(*h)); + const char *xname = fix_win_serial_name(port_name); + + gbser__db(2, "Translated port name: \"%s\"\n", xname); + + h->magic = MYMAGIC; + + comport = CreateFile(xname, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + goto failed; + } + + h->comport = comport; + h->timeout = 1; + if (gbser_set_port(h, 4800, 8, 0, 1) || set_rx_timeout(h, 0)) { + goto failed; + } + + return h; + +failed: + if (comport) { + CloseHandle(h->comport); + } + xfree(h); + + return NULL; +} + +/* Close a serial port + */ +void gbser_deinit(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + + CloseHandle(h->comport); + + xfree(h); +} + +int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { + gbser_handle *h = gbser__get_handle(handle); + DCB tio; + + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } + + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } + + tio.DCBlength = sizeof(DCB); + GetCommState(h->comport, &tio); + + tio.BaudRate = mkspeed(speed); + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = bits; + tio.Parity = parity == 0 ? NOPARITY : + (parity == 1 ? ODDPARITY : EVENPARITY); + tio.StopBits = stop == 1 ? ONESTOPBIT : TWOSTOPBITS; + + if (!SetCommState(h->comport, &tio)) { + return gbser_ERROR; + } + return gbser_OK; +} + +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { + gbser_handle *h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char *cp = *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void *) cp; + return count; +} + +/* Return when the input buffer contains at least |want| bytes or |*ms| + * milliseconds have elapsed. |ms| may be NULL or |*ms| may be zero to + * poll the port for available bytes and return immediately. |*ms| will + * be updated to indicate the remaining time on exit. + * Returns the number of bytes available (>=0) or an error code (<0). + */ +int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { + int rc; + gbser_handle *h = gbser__get_handle(handle); + + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } + + if (NULL == ms || 0 == *ms) { + DWORD err, nread; + COMSTAT stat; + ClearCommError(h->comport, &err, &stat); + if (stat.cbInQue > 0) { + DWORD count = want - h->inbuf_used; + if (count > stat.cbInQue) { + count = stat.cbInQue; + } + if (rc = set_rx_timeout(h, 1), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + count, &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; + } + } + h->inbuf_used += nread; + } + } else { + hp_time tv; + double time_left; + DWORD err, nread; + get_time(&tv); + if (rc = set_rx_timeout(h, *ms), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + want - h->inbuf_used, + &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; + } + } + h->inbuf_used += nread; + time_left = *ms - elapsed(&tv); + *ms = time_left < 0 ? 0 : (unsigned) time_left; + } + + return h->inbuf_used; +} + +/* Discard any pending input on the serial port. + */ +int gbser_flush(void *handle) { + gbser_handle *h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (!PurgeComm(h->comport, PURGE_RXCLEAR)) { + return gbser_ERROR; + } + return gbser_OK; +} + +/* Write |len| bytes from |buf| to the serial port. + */ +int gbser_write(void *handle, const void *buf, unsigned len) { + gbser_handle *h = gbser__get_handle(handle); + DWORD nwritten; + const char *bp = buf; + /* Not sure we need to spin here - but this'll work even if we don't */ + while (len > 0) { + if (!WriteFile(h->comport, bp, len, &nwritten, NULL)) { + return gbser_ERROR; + } + len -= nwritten; + bp += nwritten; + } + return gbser_OK; +} + +/* Return true if a port name seems to refer to a serial port. + * On Windows this tests the filename (against the regex + * /^(\\\\\.\\\\)?com\d+:?$/i). On Posix it returns the value of + * isatty() + */ + +int gbser_is_serial(const char *port_name) { + const char *pfx = DEV_PREFIX; + size_t pfx_l = strlen(pfx); + const char *com = "COM"; + size_t com_l = strlen(com); + unsigned digits; + + if (NULL == port_name) { + return 0; + } + + /* Skip any prefix */ + if (memcmp(port_name, pfx, pfx_l) == 0) { + port_name += pfx_l; + } + + if (case_ignore_strncmp(port_name, com, com_l) != 0) { + return 0; + } + + port_name += com_l; + for (digits = 0; isdigit(*port_name); port_name++, digits++) { + /* do nothing */ + } + + if (digits == 0) { + return 0; + } + + if (*port_name == ':') { + port_name++; + } + + if (*port_name != '\0') { + return 0; + } + + /* Success! */ + return 1; +} + +/* Read from the serial port until the specified |eol| character is + * found. Any character matching |discard| will be discarded. To + * read lines terminated by 0x0A0x0D discarding linefeeds use + * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); + */ +int gbser_read_line(void *handle, void *buf, + unsigned len, unsigned ms, + int eol, int discard) { + char *bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; + } + } +} diff --git a/gbsleep.c b/gbsleep.c new file mode 100644 index 000000000..a4b9ed6be --- /dev/null +++ b/gbsleep.c @@ -0,0 +1,51 @@ +/* + OS abstraction to sleep a given number of milliseconds. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "config.h" + +#if __WIN32__ + +#include +void +gb_sleep(unsigned long microseconds) +{ + Sleep(microseconds/1000 + 1); +} + +#elif defined HAVE_NANOSLEEP + +#include +void +gb_sleep(unsigned long microseconds) +{ + struct timespec req; + req.tv_sec = microseconds / 1000000; + req.tv_nsec = (microseconds * 1000) % 1000000000; + nanosleep(&req, NULL); +} +#elif defined HAVE_SLEEP +/* Amazingly underachieving, but probably "good enough" */ +#include +void +gb_sleep(unsigned long microseconds) +{ + sleep(microseconds / 1000000); +} +#endif diff --git a/gbtypes.h b/gbtypes.h index bdbc8ce5f..ad16fc88a 100644 --- a/gbtypes.h +++ b/gbtypes.h @@ -19,6 +19,10 @@ */ +#ifndef gb_types_h_included +#define gb_types_h_included + + /* * If this is a problem and any interesting system doesn't have the C99-ism * of we'll come up with something more clever that'll likely @@ -45,4 +49,8 @@ typedef uint16_t gbuint16; typedef int32_t gbint32; typedef int16_t gbint16; -#endif // defined(_MSC_VER) +#endif /* defined(_MSC_VER) */ + +typedef gbuint32 gbsize_t; + +#endif /* gb_types_h_included */ diff --git a/gcdb.c b/gcdb.c index 8f9727736..aeb6723f1 100644 --- a/gcdb.c +++ b/gcdb.c @@ -20,6 +20,7 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" @@ -50,8 +51,8 @@ struct dbrec { static FILE *file_in; static FILE *file_out; static const char *out_fname; -struct pdb *opdb; -struct pdb_record *opdb_rec; +static struct pdb *opdb; +static struct pdb_record *opdb_rec; static char *tbuf = NULL; static char *tbufp = NULL; @@ -338,5 +339,8 @@ ff_vecs_t gcdb_vecs = { wr_deinit, data_read, data_write, - NULL + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/gdb.c b/gdb.c index 2db870f5d..460c78d28 100644 --- a/gdb.c +++ b/gdb.c @@ -1,7 +1,7 @@ /* Garmin GPS Database Reader/Writer - Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org Mainly based on mapsource.c, Copyright (C) 2005 Robert Lipe, robertlipe@usa.net @@ -32,15 +32,36 @@ new option "ver" fixed compiler warnings 2005/07/29: fixed compiler warnings + 2005/08/04: Read/write URL (reference data changed) + 2005/08/11: Display sym and name in GDB + 2005/08/12: Neuter proximity and depth for now + 2005/08/29: big CET merge + 2005/09/13: Make sure routes have unique wpt names + 2005/10/10: MSVC fixes from Andrew + 2005/10/17: RJL: Tighten up types of a short handle. It's now a "real" type and not a void * + 2005/10/31: RJL: Add v3 format, min/max, provide defaults, data types, etc + 2005/11/09: RJL: Clarify help text for dropping via points + 2005/12/01: changed waypt's URL to descr for hidden waypoints (-> reference data changed) + removed unused procedure gdb_add_to_hidden + 2005/12/04: additional testo sequences + 2006/02/24: last field of a route is rte url + 2006/02/25: rte_read_loop: zero check replaced with a dummy read (8 unknown bytes) + 2006/03/05: first implementation of Garmin special data (garmin_fs) + 2006/04/04: Use track_add_wpt for all tracks + 2006/04/19: add url i/o to tracks and routes + 2006/04/19: check for empty waypoint shortnames (paranioa) + 2006/11/01: Use version of GPSBabel and date/time of gdb.c (managed by CVS) for watermark */ #include #include #include +#include #include "defs.h" #include "garmin_tables.h" #include "jeeps/gpsmath.h" +#include "garmin_fs.h" #define MYNAME "gdb" @@ -57,7 +78,6 @@ #define GDB_NOTES_BUFFERLEN 4096 /* (likewise) */ #define DEFAULTICONVALUE 18 -#define DEFAULTICONDESCR "Waypoint" #ifdef UTF8_SUPPORT # define GDB_UTF8_ENABLED 1 @@ -65,15 +85,12 @@ # define GDB_UTF8_ENABLED 0 #endif -typedef enum { - GDB_DISPLAY_SYMBOL_ONLY = 0, - GDB_DISPLAY_SYMBOL_AND_NAME = 1, - GDB_DISPLAY_SYMBOL_AND_COMMENT = 2, -} gdb_display_type; - /* %%% local vars %%% */ -FILE *fin, *fout; +/* static char gdb_release[] = "$Revision: 1.43 $"; */ +static char gdb_release_date[] = "$Date: 2006/11/01 22:23:39 $"; + +static FILE *fin, *fout; static char *fin_name, *fout_name; static int gdb_ver = 1; @@ -81,8 +98,8 @@ static int gdb_debug = 0; static int gdb_via; /* 0 = read and write hidden points too; 1 = drop */ static int gdb_category; -route_head *gdb_hidden = NULL; - +static queue gdb_hidden; +static short_handle gdb_short_handle; #define GDB_OPT_VER "ver" #define GDB_OPT_VIA "via" @@ -94,29 +111,18 @@ static char *gdb_opt_via = NULL; static arglist_t gdb_args[] = { {GDB_OPT_CATEGORY, &gdb_opt_category, - "Default category on output (1..16)", NULL, ARGTYPE_INT}, + "Default category on output (1..16)", NULL, ARGTYPE_INT, "1", "16"}, {GDB_OPT_VER, &gdb_opt_ver, - "Version of gdb file to generate (1,2)", "2", ARGTYPE_INT}, + "Version of gdb file to generate (1,2)", "2", ARGTYPE_INT, "1", "2"}, {GDB_OPT_VIA, &gdb_opt_via, - "Drop route points, if they don't have an aquivalent waypoint (hidden points)", NULL, ARGTYPE_BOOL}, - {0, 0, 0, 0, 0} + "Drop route points that do not have an equivalent waypoint (hidden points)", NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR }; /********************************************************************************************************/ /* %%% 1-1 functions from mapsource, should by shared!!! %%% */ -/* - * Add a waypoint that we've already written out to our list - * - */ -static void -gdb_add_to_hidden(const waypoint *wpt) -{ - waypoint *tmp = waypt_dupe(wpt); - route_add_wpt(gdb_hidden, tmp); -} - static waypoint * gdb_find_wpt_q_by_name(const queue *whichQueue, const char *name) { @@ -125,147 +131,25 @@ gdb_find_wpt_q_by_name(const queue *whichQueue, const char *name) QUEUE_FOR_EACH(whichQueue, elem, tmp) { waypointp = (waypoint *) elem; - if (0 == strcmp(waypointp->shortname, name)) { + if (0 == case_ignore_strcmp(waypointp->shortname, name)) { return waypointp; } } return NULL; } -static const char * -gdb_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format) -{ - static char custom[] = "Custom 63"; - icon_mapping_t *i; - - if (icon >= 500 && icon <= 563) - { - snprintf(custom, sizeof(custom), "Custom %d", icon - 500); - return &custom[0]; - } - - for (i = garmin_icon_table; i->icon; i++) { - switch (garmin_format) { - case MAPSOURCE: - if (icon == i->mpssymnum) - return i->icon; - break; - case PCX: - case GARMIN_SERIAL: - if (icon == i->pcxsymnum) - return i->icon; - break; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - return DEFAULTICONDESCR; -} - -static int -gdb_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) -{ - icon_mapping_t *i; - int def_icon = DEFAULTICONVALUE; - int n; - - if (!desc) - return def_icon; - - /* - * If we were given a numeric icon number as a description - * (i.e. 8255), just return that. - */ - n = atoi(desc); - if (n) { - return n; - } - - for (i = garmin_icon_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - switch (garmin_format) { - case MAPSOURCE: - return i->mpssymnum; - case PCX: - case GARMIN_SERIAL: - return i->pcxsymnum; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - } - return def_icon; -} - static int gdb_detect_rtept_class(const waypoint *wpt) { - if (gdb_find_wpt_q_by_name((queue *)&gdb_hidden->waypoint_list, wpt->shortname) == NULL) + if (gdb_find_wpt_q_by_name((queue *)&gdb_hidden, wpt->shortname) == NULL) return (int)GDB_HIDDENROUTEWPTCLASS; else return (int)GDB_DEFAULTWPTCLASS; } -#ifndef UTF8_SUPPORT -static char *gdb_garmin_to_utf8(const char *s) -{ - int len; - char *res; - unsigned char c; - char *src, *dst; - - if (s == NULL) return NULL; - - len = 0; - src = (char *)s; - while ('\0' != (c = *src++)) - { - len++; - if (c & 0x80) len++; - if (c == 0x80) len++; - } - - src = (char *)s; - dst = res = (void *) xmalloc(len + 1); - while ('\0' != (c = *src++)) - { - if (c == 0x80) - { - *dst++ = 0xe2; - *dst++ = 0x82; - *dst++ = 0xac; - } - else if (c & 0x80) - { - *dst++ = (0xc0 | (c >> 6)); - *dst++ = (c & 0xbf); - } - else - { - *dst++ = c; - } - } - *dst = '\0'; - return res; -} -#endif - /* %%% local functions (read support) %%% */ -static char * -gdb_convert_name_buff(char *buff, size_t buffsize) -{ -#ifdef UTF8_SUPPORT - char *tmp = str_garmin_to_utf8(buff); -#else - char *tmp = gdb_garmin_to_utf8(buff); -#endif - strncpy(buff, tmp, buffsize); - xfree(tmp); - return buff; -} - #ifdef GDB_DEBUG static void gdb_print_buff(const char *buff, int count, const char *comment) @@ -290,10 +174,13 @@ gdb_create_rte_wpt(const char *name, double lat, double lon, double alt) if (wpt == NULL) { if (gdb_via != 0) return NULL; - wpt = gdb_find_wpt_q_by_name((queue *)&gdb_hidden->waypoint_list, name); + wpt = gdb_find_wpt_q_by_name((queue *)&gdb_hidden, name); + } + if (wpt != NULL) + { + wpt = waypt_dupe(wpt); +// wpt->creation_time = 0; /* !!! should be removed !!! */ } - if (wpt != NULL) - wpt = waypt_dupe(wpt); else { wpt = waypt_new(); @@ -346,10 +233,11 @@ gdb_fread_str(char *dest, size_t maxlen) } } fatal(MYNAME ": local buffer overflow detected, please report!\n"); + return 0; } static int -gdb_fread_le(void *dest, size_t size, int bit_count, const char *prefix, const char *field) +gdb_fread_le(void *dest, size_t size, const unsigned int bit_count, const char *prefix, const char *field) { char buff[32]; unsigned char *c = dest; @@ -389,6 +277,7 @@ gdb_fread_le(void *dest, size_t size, int bit_count, const char *prefix, const c default: fatal(MYNAME "%s: unsupported bit count (%d) in gdb_le_read!\n", prefix, bit_count); } + return 0; } static int @@ -479,7 +368,7 @@ gdb_read_file_header(void) gdb_fread(&reclen, 4); reclen = le_read32(&reclen); - gdb_is_valid(reclen < sizeof(buff), prefix, "Invalid record length"); + gdb_is_valid(reclen < (int)sizeof(buff), prefix, "Invalid record length"); gdb_fread(buff, reclen); gdb_is_valid(0 == gdb_fread_str(buff, sizeof(buff)), prefix, "header"); @@ -499,17 +388,23 @@ gdb_read_wpt(const size_t fileofs, int *wptclass) char xnotes[GDB_NOTES_BUFFERLEN]; char xurl[GDB_URL_BUFFERLEN]; int xclass; - int xlat, xlon, xdisplay, xcolour, xicon, xtime; + int xlat, xlon, xdisplay, xcolour, xicon, xtime, dynamic; short xcat; double xdepth = unknown_alt; double xalt = unknown_alt; double xproximity = unknown_alt; + double xtemp; waypoint *res; char buff[128]; size_t pos, delta; + garmin_fs_t *gmsd = NULL; const char *prefix = "wpt_read"; + res = waypt_new(); + + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&res->fs, (format_specific_data *) gmsd); /********************************************************************************************************/ /* record structure @@ -540,52 +435,89 @@ gdb_read_wpt(const size_t fileofs, int *wptclass) /********************************************************************************************************/ gdb_is_valid(gdb_fread_str(xname, sizeof(xname)) > 0, prefix, "new waypoint"); - gdb_convert_name_buff(xname, sizeof(xname)); + res->shortname = xstrdup(xname); gdb_fread_le(&xclass, sizeof(xclass), 32, prefix, "class"); - gdb_fread_str(buff, sizeof(buff)); /* country */ + GMSD_SET(wpt_class, xclass); + + gdb_fread_str(buff, sizeof(buff)); /* country code */ + GMSD_SETSTR(cc, buff); gdb_fread(buff, 22); xlat = gdb_fread_le(&xlat, sizeof(xlat), 32, prefix, "latitude"); xlon = gdb_fread_le(&xlon, sizeof(xlon), 32, prefix, "longitude"); - if (gdb_fread_flag(1)) /* altitude flag */ + if (gdb_fread_flag(1)) { /* altitude flag */ gdb_fread_le(&xalt, sizeof(xalt), 64, prefix, "altitude"); + if (xalt > 1.0e24) + xalt = unknown_alt; + } gdb_fread_str(xnotes, sizeof(xnotes)); /* notes */ - gdb_convert_name_buff(xnotes, sizeof(xnotes)); - if (gdb_fread_flag(1)) /* proximity flag */ + if (gdb_fread_flag(1)) { /* proximity flag */ gdb_fread_le(&xproximity, sizeof(xproximity), 64, prefix, "proximity"); + GMSD_SET(proximity, xproximity); + } xdisplay = gdb_fread_le(&xdisplay, sizeof(xdisplay), 32, prefix, "display"); + switch(xdisplay) { + case gt_gdb_display_mode_symbol: + xdisplay = gt_display_mode_symbol; + break; + case gt_gdb_display_mode_symbol_and_comment: + xdisplay = gt_display_mode_symbol_and_comment; + break; + default: /* gt_gdb_display_mode_symbol_and_name and others */ + xdisplay = gt_display_mode_symbol_and_name; + break; + } + GMSD_SET(display, xdisplay); + xcolour = gdb_fread_le(&xcolour, sizeof(xcolour), 32, prefix, "colour"); + xicon = gdb_fread_le(&xicon, sizeof(xicon), 32, prefix, "icon"); + GMSD_SET(icon, xicon); gdb_fread_str(buff, sizeof(buff)); /* city */ + GMSD_SETSTR(city, buff); + gdb_fread_str(buff, sizeof(buff)); /* state */ + GMSD_SETSTR(state, buff); + gdb_fread_str(buff, sizeof(buff)); /* facility */ + GMSD_SETSTR(facility, buff); gdb_fread(buff, 1); /* unknown */ - if (gdb_fread_flag(1)) /* depth flag */ + if (gdb_fread_flag(1)) { /* depth flag */ gdb_fread_le(&xdepth, sizeof(xdepth), 64, prefix, "depth"); + GMSD_SET(depth, xdepth); + } gdb_fread(buff, 1); gdb_fread(buff, 1); if (gdb_fread_flag(0)) - gdb_fread(buff, 4); - else gdb_fread(buff, 3); + else + gdb_fread(buff, 2); + + do /* undocumented & unused string */ + { + gdb_fread(buff, 1); + } + while (buff[0] != 0); - gdb_fread_str(xurl, sizeof(xurl)); - gdb_convert_name_buff(xurl, sizeof(xurl)); + gdb_fread_str(xurl, sizeof(xurl)); /* URL */ xcat = gdb_fread_le(&xcat, sizeof(xcat), 16, prefix, "category"); + if (xcat != 0) GMSD_SET(category, xcat); - if (gdb_fread_flag(1)) /* temperature flag */ - gdb_fread(buff, 8); /* temperature */ + if (gdb_fread_flag(1)) { /* temperature flag */ + gdb_fread_le(&xtemp, sizeof(xtemp), 64, prefix, "temperature"); + GMSD_SET(temperature, xtemp); + } /* Here comes 1 .. 6 unknown bytes !!! 6 only if class > 0 !!! @@ -604,7 +536,7 @@ gdb_read_wpt(const size_t fileofs, int *wptclass) xtime = 0; if (gdb_fread_flag(1)) { - gdb_is_valid(delta==5, prefix, "Waypoint time"); + gdb_is_valid((delta == 5), prefix, "Waypoint time"); gdb_fread_le(&xtime, sizeof(xtime), 32, prefix, "time"); } else @@ -612,24 +544,22 @@ gdb_read_wpt(const size_t fileofs, int *wptclass) *wptclass = xclass; - res = waypt_new(); - res->shortname = xstrdup(xname); - if (xurl[0] != '\0') res->url = xstrdup(xurl); + if (xurl[0] != '\0') + { + if (xclass == 0) + res->url = xstrdup(xurl); + else + res->description = xstrdup(xurl); + } if (xnotes[0] != '\0') res->notes = xstrdup(xnotes); res->latitude = GPS_Math_Semi_To_Deg(xlat); res->longitude = GPS_Math_Semi_To_Deg(xlon); res->altitude = xalt; res->creation_time = xtime; -#if 0 - res->depth = xdepth; - res->proximity = xproximity; - res->garmin_data = xcalloc(1, sizeof(garmin_data_t)); - res->garmin_data->colour = xcolour; - res->garmin_data->category = xcat; - res->garmin_data->display = xdisplay; -#endif + /* might need to change this to handle version dependent icon handling */ - res->icon_descr = gdb_find_desc_from_icon_number(xicon, MAPSOURCE); + res->icon_descr = gt_find_desc_from_icon_number(xicon, GDB, &dynamic); + res->wpt_flags.icon_descr_is_dynamic = dynamic; gdb_is_validf(fabs(res->latitude) <= 90.0, prefix, "%s has invalid latitude (%f)", res->shortname, res->latitude); @@ -661,13 +591,12 @@ gdb_read_route(void) route_head *route; waypoint *wpt; - const char *prefix = "rte_read_head"; - const char *prefix1 = "rte_read_loop"; - const char *prefix2 = "rte_ils_loop"; - const char *prefix3 = "rte_read_final"; + const char prefix[] = "rte_read_head"; + const char prefix1[] = "rte_read_loop"; + const char prefix2[] = "rte_ils_loop"; + const char prefix3[] = "rte_read_final"; gdb_is_valid(gdb_fread_str(xname, sizeof(xname)) > 0, prefix, "Route has no name"); - gdb_convert_name_buff(xname, sizeof(xname)); gdb_fread_le(&auto_name, sizeof(auto_name), 8, prefix, "auto name"); if (gdb_fread_flag(0)) /* max. data flag */ @@ -695,22 +624,26 @@ gdb_read_route(void) route->rte_name = xstrdup(xname); route_add_head(route); -#ifdef GDB_DEBUG - printf(MYNAME " - route: \"%s\" with %d point(s)\n", xname, count); -#endif origin = count; while (count--) { + garmin_fs_t *gmsd = NULL; + garmin_ilink_t *anchor; + gdb_fread_str(xwptname, sizeof(xwptname)); /* waypoint name */ - gdb_convert_name_buff(xwptname, sizeof(xwptname)); gdb_fread_le(&xclass, sizeof(xclass), 32, prefix1, "class"); /* class */ gdb_fread_str(buff, sizeof(buff)); /* country */ gdb_fread(buff, 22); /* sub class data */ gdb_fread(buff, 1); - gdb_is_valid(buff[0] == 0, prefix1, "Should by zero byte (1)"); + if (buff[0] != 0) { /* 0x00 or 0xFF */ + gdb_fread(buff, 8); /* unknown 8 bytes */ +#ifdef GDB_DEBUG + gdb_print_buff(buff, 8, "Unknown bytes within rte_reed_loop"); +#endif + } /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ /* OK: this should be, but i've seen exceptions (...cannot verify the first byte */ @@ -728,8 +661,9 @@ gdb_read_route(void) if (gdb_ver > 1) gdb_fread(buff, 8); /* Unknown 8 bytes since gdb v2 */ - gdb_fread(buff, 1); - gdb_is_valid((buff[0] == 0), prefix3, "last seq.(2)"); + gdb_fread_str(xname, sizeof(xname)); + if (buff[0] != 0) + route->rte_url = xstrdup(xname); wpt = gdb_create_rte_wpt(xwptname, xlat, xlon, xalt); if (wpt != NULL) @@ -750,8 +684,20 @@ gdb_read_route(void) xalt = unknown_alt; wpt = gdb_create_rte_wpt(xwptname, xlat, xlon, xalt); - if (wpt != NULL) + if (wpt != NULL) { route_add_wpt(route, wpt); + gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + GMSD_SET(wpt_class, xclass); + } + else { + gmsd = NULL; + } + + anchor = NULL; while (--isteps > 0) { @@ -764,6 +710,23 @@ gdb_read_route(void) xlat = GPS_Math_Semi_To_Deg(semilat); xlon = GPS_Math_Semi_To_Deg(semilon); gdb_is_validf(fabs(xlat) <= 90.0, prefix2, "Invalid latitude (%f)", xlat); + + if (gmsd != NULL) + { + garmin_ilink_t *ilink_ptr = xmalloc(sizeof(*ilink_ptr)); + + ilink_ptr->ref_count = 1; + ilink_ptr->lat = xlat; + ilink_ptr->lon = xlon; + ilink_ptr->next = NULL; + + if (anchor == NULL) { + gmsd->ilinks = ilink_ptr; + } else { + anchor->next = ilink_ptr; + } + anchor = ilink_ptr; + } } gdb_fread(buff, 1); @@ -788,6 +751,7 @@ gdb_read_route(void) /* This should normally never happen; end of route is handled in main loop before this */ fatal(MYNAME "-%s: Unexpected end of route \"%s\"!", prefix1, xname); + return 0; } @@ -814,7 +778,6 @@ gdb_read_track(const size_t max_file_pos) const char *prefix = "trk_read_loop"; gdb_fread_str(xname, sizeof(xname)); - gdb_convert_name_buff(xname, sizeof(xname)); gdb_fread_le(&xdisplay, sizeof(xdisplay), 8, prefix0, "display"); gdb_fread_le(&xcolour, sizeof(xcolour), 32, prefix0, "colour"); @@ -856,10 +819,12 @@ gdb_read_track(const size_t max_file_pos) gdb_is_validf(fabs(wpt->latitude) <= 90.0, prefix, "Invalid latitude (%f)", wpt->latitude); - route_add_wpt(track, wpt); + track_add_wpt(track, wpt); } - gdb_fread(buff, 1); + gdb_fread_str(xname, sizeof(xname)); + if (xname[0] != '\0') + track->rte_url = xstrdup(xname); return track; } @@ -869,6 +834,7 @@ gdb_read_track(const size_t max_file_pos) static void gdb_read_data(void) { + queue *elem, *temp; int reclen, warnings; char typ; size_t curpos, anchor; @@ -876,8 +842,7 @@ gdb_read_data(void) const char *prefix = "main_read_loop"; - gdb_hidden = route_head_alloc(); - track_add_head(gdb_hidden); + QUEUE_INIT(&gdb_hidden); warnings = 0; @@ -903,10 +868,11 @@ gdb_read_data(void) wpt = gdb_read_wpt(curpos + reclen, &wptclass); if (wpt != NULL ) { - if (wptclass == 0) - waypt_add(wpt); + if (wptclass == 0) { + waypt_add(wpt); + } else if (gdb_via == 0) - route_add_wpt(gdb_hidden, wpt); + ENQUEUE_TAIL(&gdb_hidden, &wpt->Q); else waypt_free(wpt); } @@ -931,6 +897,7 @@ gdb_read_data(void) clearerr(fin); fseek(fin, anchor, SEEK_SET); + while (feof(fin) == 0) { gdb_fread_le(&reclen, sizeof(reclen), 32, prefix, "record length"); @@ -979,9 +946,10 @@ gdb_read_data(void) fseek(fin, curpos + reclen, SEEK_SET); } } - - /* finally kill our temporary queue */ - track_del_head(gdb_hidden); + + QUEUE_FOR_EACH(&gdb_hidden, elem, temp) { /* finally kill our temporary queue */ + waypt_free((waypoint *) elem); + } } /*******************************************************************************/ @@ -1035,9 +1003,8 @@ gdb_fwrite_str(const char *str, const int len) gdb_fwrite(str, len); /* write a string with fixed length */ else { - char *tmp = str_utf8_to_cp1252((str != NULL) ? str : ""); + char *tmp = (str != NULL) ? (char *)str : ""; gdb_fwrite(tmp, strlen(tmp) + 1); - xfree(tmp); } } @@ -1072,7 +1039,8 @@ gdb_fwrite_le(const void *data, const size_t size) break; default: - fatal(MYNAME "-write_le: Unsupported data size (%ld)!\n", size); + fatal(MYNAME "-write_le: Unsupported data size (%lu)!\n", + (unsigned long) size); } } @@ -1115,10 +1083,10 @@ gdb_fwrite_icon(const waypoint *wpt) /* partly taken from mapsource.c */ else { /* might need to change this to handle version dependent icon handling */ - icon = gdb_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { - icon = gdb_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); } } gdb_fwrite_le(&icon, sizeof(icon)); @@ -1129,11 +1097,12 @@ gdb_fwrite_icon(const waypoint *wpt) /* partly taken from mapsource.c */ /*-----------------------------------------------------------------------------*/ static void -gdb_write_file_header(const struct tm *tm) +gdb_write_file_header(void) { - char buff[128]; + char buff[128], tbuff[32]; char *c; int len; + struct tm tm; gdb_fwrite_str("MsRcf", -1); gdb_fwrite_int(2); @@ -1143,11 +1112,30 @@ gdb_write_file_header(const struct tm *tm) gdb_fwrite_str(buff, -1); #if 0 + /* Take this if anything is wrong with our self generated watermark */ strncpy(buff, "A].SQA*Dec 27 2004*17:40:51", sizeof(buff)); /* MapSource V6.5 */ #else /* This is our "Watermark" to show this file was created by GPSbabel */ - /* !!! We should define the date use through Makefile !!! */ - strncpy(buff, "A].GPSBabel_1.2.7-beta*Aug 12 2005*19:55:05", sizeof(buff)); /* gpsbabel V1.2.7 BETA */ + + /* history: + strncpy(buff, "A].GPSBabel_1.2.7-beta*Sep 13 2005*20:10:00", sizeof(buff)); // gpsbabel V1.2.7 BETA + strncpy(buff, "A].GPSBabel_1.2.8-beta*Jan 18 2006*20:11:00", sizeof(buff)); // gpsbabel 1.2.8-beta01182006_clyde + strncpy(buff, "A].GPSBabel_1.2.8-beta*Apr 18 2006*20:12:00", sizeof(buff)); // gpsbabel 1.2.8-beta20060405 + strncpy(buff, "A].GPSBabel-1.3*Jul 02 2006*20:13:00", sizeof(buff)); // gpsbabel 1.3.0 + strncpy(buff, "A].GPSBabel-1.3.1*Sep 03 2006*20:14:00", sizeof(buff)); // gpsbabel 1.3.1 + */ + + /* + New since 11/01/2006: + version: version and release of gpsbabel (defined in configure.in) + timestamp: date and time of gdb.c (handled by CVS) + */ + memset(&tm, 0, sizeof(tm)); + sscanf(gdb_release_date+7, "%d/%d/%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + tm.tm_year -= 1900; + tm.tm_mon -= 1; + strftime(tbuff, sizeof(tbuff), "%b %d %Y*%H:%M:%S", &tm); + snprintf(buff, sizeof(buff), "A].GPSBabel-%s*%s", gpsbabel_version, tbuff); #endif len = strlen(buff); buff[2] = 2; @@ -1161,6 +1149,22 @@ gdb_write_file_header(const struct tm *tm) gdb_fwrite_str("MapSource", -1); /* MapSource magic */ } +static void +gdb_reset_short_handle(void) +{ + if (gdb_short_handle != NULL) + mkshort_del_handle(&gdb_short_handle); + + gdb_short_handle = mkshort_new_handle(); + + setshort_length(gdb_short_handle, GDB_NAME_BUFFERLEN); + setshort_badchars(gdb_short_handle, ""); + setshort_mustupper(gdb_short_handle, 0); + setshort_mustuniq(gdb_short_handle, 1); + setshort_whitespace_ok(gdb_short_handle, 1); + setshort_repeating_whitespace_ok(gdb_short_handle, 1); +} + /*******************************************************************************/ /* %%% write waypoints %%% */ /*-----------------------------------------------------------------------------*/ @@ -1172,6 +1176,11 @@ gdb_write_waypt(const waypoint *wpt, const int hidden) char ffbuf[32], zbuf[32]; char c0 = 0; char c1 = 1; + garmin_fs_t *gmsd; + unsigned char wpt_class; + char *ident; + + gmsd = GMSD_FIND(wpt); gdb_is_validf((fabs(wpt->latitude) <= 90), "wpt_write", "%s: Invalid latitude (%f) detected\n", wpt->shortname, wpt->latitude); @@ -1179,11 +1188,16 @@ gdb_write_waypt(const waypoint *wpt, const int hidden) memset(ffbuf, 0xFF, sizeof(ffbuf)); memset(zbuf, 0x00, sizeof(zbuf)); - gdb_fwrite_str(wpt->shortname, -1); + ident = wpt->shortname; /* paranoia */ + if (global_opts.synthesize_shortnames || (ident == NULL) || (*ident == '\0')) + { + ident = mkshort_from_wpt(gdb_short_handle, wpt); + } + gdb_fwrite_str(ident, -1); - gdb_fwrite_int( (hidden != 0) ? - GDB_HIDDENROUTEWPTCLASS : GDB_DEFAULTWPTCLASS); /* class */ - gdb_fwrite_str("", -1); /* country */ + wpt_class = GMSD_GET(wpt_class, (hidden != 0) ? GDB_HIDDENROUTEWPTCLASS : GDB_DEFAULTWPTCLASS); + gdb_fwrite_int(wpt_class); /* class */ + gdb_fwrite_str(GMSD_GET(cc, ""), -1); /* country code */ gdb_fwrite(zbuf, 4); /* subclass part 1 */ gdb_fwrite(ffbuf, 12); /* subclass part 2 */ @@ -1197,49 +1211,38 @@ gdb_write_waypt(const waypoint *wpt, const int hidden) gdb_fwrite_str((wpt->notes != NULL) ? wpt->notes : wpt->description, -1); /* notes/comment/descr */ -#if 0 - if (garmin_data != NULL) - { - gdb_fwrite_alt(garmin_data->proximity, 0); /* proximity */ - gdb_fwrite_int(garmin_data->display); /* display */ - gdb_fwrite_int(garmin_data->colour); /* colour */ - { - gdb_fwrite(&c0, 1); /* NO proximity */ - gdb_fwrite_int(GDB_DISPLAY_SYMBOL_AND_NAME); /* display */ - gdb_fwrite_int(0); /* colour */ - + gdb_fwrite_alt(GMSD_GET(proximity, 0), 0); /* proximity */ + + switch(GMSD_GET(display, 0)) { /* display */ + case gt_display_mode_symbol: i = gt_gdb_display_mode_symbol; break; + case gt_display_mode_symbol_and_comment: i = gt_gdb_display_mode_symbol_and_comment; break; + default: i = gt_gdb_display_mode_symbol_and_name; break; } -#else - gdb_fwrite(&c0, 1); /* NO proximity */ - gdb_fwrite_int(GDB_DISPLAY_SYMBOL_AND_NAME); /* display */ - gdb_fwrite_int(0); /* colour */ -#endif - gdb_fwrite_icon(wpt); /* icon */ - gdb_fwrite_str("", -1); /* city */ - gdb_fwrite_str("", -1); /* state */ - gdb_fwrite_str("", -1); /* facility */ - gdb_fwrite(zbuf, 1); /* unknown */ -#if 0 - gdb_fwrite_alt((garmin_data != NULL) ? garmin_data->depth : 0, 0); /* depth */ -#else - gdb_fwrite(&c0, 1); /* NO depth */ -#endif - gdb_fwrite(zbuf, 3); /* three unknown bytes */ - gdb_fwrite(zbuf, 4); /* four unknown bytes */ + gdb_fwrite_int(i); - gdb_fwrite_str(wpt->url, -1); /* URL */ + gdb_fwrite_int(0); /* colour */ -#if 0 - if (gdb_opt_category != NULL) /* category */ - i = gdb_category; + gdb_fwrite_icon(wpt); /* icon */ + gdb_fwrite_str(GMSD_GET(city, ""), -1); /* city */ + gdb_fwrite_str(GMSD_GET(state, ""), -1); /* state */ + gdb_fwrite_str(GMSD_GET(facility, ""), -1); /* facility */ + + gdb_fwrite(zbuf, 1); /* unknown */ + + gdb_fwrite_alt(GMSD_GET(depth, 0), 0); /* depth */ + + gdb_fwrite(zbuf, 3); /* three unknown bytes */ + gdb_fwrite(zbuf, 4); /* four unknown bytes */ + + if (hidden == 0) + gdb_fwrite_str(wpt->url, -1); /* URL */ else - i = (wpt->garmin_data != NULL) ? wpt->garmin_data->category : 0; -#else - i = gdb_category; -#endif + gdb_fwrite_str(wpt->description, -1); /* description for hidden waypoints */ + + i = GMSD_GET(category, gdb_category); /* category */ gdb_fwrite_le(&i, 2); - gdb_fwrite(zbuf, 1); /* temperature flag */ + gdb_fwrite_alt(GMSD_GET(temperature, 0), 0); /* temperature */ if (wpt->creation_time != 0) /* creation time */ { @@ -1256,9 +1259,10 @@ gdb_write_waypt_cb(const waypoint *wpt) /* called by waypt_disp over all waypo { int reclen; size_t pos; + waypoint *tmp; /* check for duplicate waypoints */ - if (NULL != gdb_find_wpt_q_by_name((queue *)&gdb_hidden->waypoint_list, wpt->shortname)) + if (NULL != gdb_find_wpt_q_by_name(&gdb_hidden, wpt->shortname)) return; gdb_fwrite_int(0); @@ -1273,7 +1277,8 @@ gdb_write_waypt_cb(const waypoint *wpt) /* called by waypt_disp over all waypo fseek(fout, pos + reclen, SEEK_SET); - route_add_wpt(gdb_hidden, waypt_dupe(wpt)); /* add tis point to our internal queue */ + tmp = waypt_dupe(wpt); + ENQUEUE_TAIL(&gdb_hidden, &tmp->Q); /* add this point to our internal queue */ } static void @@ -1281,9 +1286,9 @@ gdb_write_rtewpt_cb(const waypoint *wpt) /* called by waypt_disp (route points) { int reclen; size_t pos; - waypoint *tmp; + waypoint *tmp, *dupe; - tmp = gdb_find_wpt_q_by_name((queue *)&gdb_hidden->waypoint_list, wpt->shortname); + tmp = gdb_find_wpt_q_by_name(&gdb_hidden, wpt->shortname); if (tmp == NULL) { tmp = find_waypt_by_name(wpt->shortname); @@ -1300,7 +1305,8 @@ gdb_write_rtewpt_cb(const waypoint *wpt) /* called by waypt_disp (route points) fseek(fout, pos + reclen, SEEK_SET); - route_add_wpt(gdb_hidden, waypt_dupe(wpt)); /* add tis point to our internal queue */ + dupe = waypt_dupe(wpt); + ENQUEUE_TAIL(&gdb_hidden, &dupe->Q); /* add this point to our internal queue */ } } @@ -1342,13 +1348,20 @@ gdb_write_route(const route_head *route, const waypoint **list, const int count) } } - if (route->rte_name == NULL) { - snprintf(buff, sizeof(buff), "Route%04d", route->rte_num); - gdb_fwrite_str(buff, -1); + char *cname; + + if (route->rte_name == NULL) + { + snprintf(buff, sizeof(buff), "Route%04d", route->rte_num); + cname = mkshort(gdb_short_handle, buff); + } + else + cname = mkshort(gdb_short_handle, route->rte_name); + + gdb_fwrite_str(cname, -1); + xfree(cname); } - else - gdb_fwrite_str(route->rte_name, -1); gdb_fwrite(&c0, 1); /* auto_name */ @@ -1370,8 +1383,13 @@ gdb_write_route(const route_head *route, const waypoint **list, const int count) for (i = 0; i < count; i++) { const waypoint *wpt = list[i]; + garmin_fs_t *gmsd; - wpt_class = gdb_detect_rtept_class(wpt); + gmsd = GMSD_FIND(wpt); + if (gmsd && gmsd->flags.wpt_class) + wpt_class = gmsd->wpt_class; + else + wpt_class = gdb_detect_rtept_class(wpt); if (prev != NULL) { @@ -1438,7 +1456,7 @@ gdb_write_route(const route_head *route, const waypoint **list, const int count) gdb_fwrite_str(wpt->shortname, -1); /* short name */ gdb_fwrite_int(wpt_class); /* class */ - gdb_fwrite_str("", -1); /* country */ + gdb_fwrite_str(GMSD_GET(cc, ""), -1); /* country */ gdb_fwrite(zbuff, 4); /* subclass part 1 */ gdb_fwrite(ffbuff, 12); /* subclass part 2 */ @@ -1460,7 +1478,7 @@ gdb_write_route(const route_head *route, const waypoint **list, const int count) if (gdb_ver > 1) gdb_fwrite(ffbuff, 8); - gdb_fwrite(&c0, 1); + gdb_fwrite_str(route->rte_url, -1); } static void @@ -1502,12 +1520,21 @@ gdb_write_track(const route_head *track) queue *elem, *tmp; int count = track->rte_waypt_ct; - if (track->rte_name == NULL) - snprintf(buff, sizeof(buff), "Track%04d", track->rte_num); - else - strncpy(buff, track->rte_name, sizeof(buff)); + { + char *cname; - gdb_fwrite_str(buff, -1); + if (track->rte_name == NULL) + { + snprintf(buff, sizeof(buff), "Track%04d", track->rte_num); + cname = mkshort(gdb_short_handle, buff); + } + else + cname = mkshort(gdb_short_handle, track->rte_name); + + gdb_fwrite_str(cname, -1); + xfree(cname); + } + gdb_fwrite(&c0, 1); /* display */ gdb_fwrite_int(0); /* xcolour */ gdb_fwrite_int(count); @@ -1532,7 +1559,7 @@ gdb_write_track(const route_head *track) gdb_fwrite_alt(wpt->depth, unknown_alt); /* depth */ gdb_fwrite(&c0, 1); /* temperature */ } - gdb_fwrite(&c0, 1); + gdb_fwrite_str(track->rte_url, -1); } static void @@ -1562,26 +1589,35 @@ gdb_write_track_cb(const route_head *track) /* called from track_disp_all */ static void gdb_write_data(void) { + queue *temp, *elem; char c1 = 1; - gdb_hidden = route_head_alloc(); /* contains all written waypts & rtepts */ - track_add_head(gdb_hidden); /* tracks comes later and we drop this before */ + QUEUE_INIT(&gdb_hidden); /* contains all written waypts & rtepts */ - if (doing_wpts) waypt_disp_all(gdb_write_waypt_cb); - if (doing_rtes) + /* (doing_wpts) */ + + gdb_reset_short_handle(); + waypt_disp_all(gdb_write_waypt_cb); + + /* (doing_rtes) */ + + gdb_reset_short_handle(); + setshort_defname(gdb_short_handle, "Route"); + if (gdb_via == 0) { - - if (gdb_via == 0) - { - /* find out all route points we have to write as a "HIDDEN CLASS" waypoint */ - route_disp_all(NULL, NULL, gdb_write_rtewpt_cb); - } - route_disp_all(gdb_write_route_cb, NULL, NULL); + /* find out all route points we have to write as a "HIDDEN CLASS" waypoint */ + route_disp_all(NULL, NULL, gdb_write_rtewpt_cb); } + route_disp_all(gdb_write_route_cb, NULL, NULL); + QUEUE_FOR_EACH(&gdb_hidden, elem, temp) { /* vaporize our temporary queue */ + waypt_free((waypoint *) elem); + } - track_del_head(gdb_hidden); /* vaporize our temporary queue */ - - if (doing_trks) track_disp_all(gdb_write_track_cb, NULL, NULL); + /* (doing_trks) */ + + gdb_reset_short_handle(); + setshort_defname(gdb_short_handle, "Track"); + track_disp_all(gdb_write_track_cb, NULL, NULL); gdb_fwrite_int(2); /* finalize gdb with empty map segment */ gdb_fwrite_str("V", -1); @@ -1615,7 +1651,7 @@ gdb_init_opts(const char op) /* 1 = read; 2 = write */ gdb_category = atoi(gdb_opt_category); if ((gdb_category < 1) || (gdb_category > 16)) fatal(MYNAME ": Unsupported category \"%s\"!\n", gdb_opt_category); - gdb_category = 1 << --gdb_category; + gdb_category = 1 << (gdb_category - 1); } gdb_ver = atoi(gdb_opt_ver); @@ -1644,6 +1680,8 @@ gdb_wr_init(const char *fname) fout_name = xstrdup(fname); fout = xfopen(fname, "wb", MYNAME); + gdb_short_handle = NULL; + QUEUE_INIT(&gdb_hidden); } static void @@ -1660,6 +1698,7 @@ gdb_wr_deinit(void) fclose(fout); xfree(fout_name); fout_name = NULL; + mkshort_del_handle(&gdb_short_handle); } static void @@ -1672,7 +1711,7 @@ gdb_read(void) static void gdb_write(void) { - gdb_write_file_header(NULL); + gdb_write_file_header(); gdb_write_data(); } @@ -1688,7 +1727,8 @@ ff_vecs_t gdb_vecs = { gdb_read, gdb_write, NULL, - gdb_args + gdb_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ }; /*******************************************************************************/ diff --git a/geo.c b/geo.c index 11cd0f72d..96f9d8d7b 100644 --- a/geo.c +++ b/geo.c @@ -20,23 +20,24 @@ #include "xmlgeneric.h" static char *deficon = NULL; +static char *nuke_placer; static waypoint *wpt_tmp; -FILE *fd; -FILE *ofd; +static FILE *ofd; static arglist_t geo_args[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING }, - {0, 0, 0, 0, 0} + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define MYNAME "geo" #define MY_CBUF 4096 -#if NO_EXPAT -void +#if ! HAVE_LIBEXPAT +static void geo_rd_init(const char *fname) { fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); @@ -89,7 +90,18 @@ void wpt_name_s(const char *args, const char **attrv) void wpt_name(const char *args, const char **unused) { - if (args) wpt_tmp->description = xstrappend(wpt_tmp->description,args); + char *s; + if (!args) return; + + wpt_tmp->description = xstrappend(wpt_tmp->description,args); + s = xstrrstr(wpt_tmp->description, " by "); + if (s) { + wpt_tmp->gc_data.placer = xstrdup(s + 4); + + if (nuke_placer) { + *s = '\0'; + } + } } void wpt_link_s(const char *args, const char **attrv) @@ -130,32 +142,32 @@ void wpt_coord(const char *args, const char **attrv) } } -void +static void geo_rd_init(const char *fname) { xml_init(fname, loc_map, NULL); } -void +static void geo_read(void) { xml_read(); } #endif -void +static void geo_rd_deinit(void) { xml_deinit(); } -void +static void geo_wr_init(const char *fname) { ofd = xfopen(fname, "w", MYNAME); } -void +static void geo_wr_deinit(void) { fclose(ofd); @@ -188,7 +200,7 @@ geo_waypt_pr(const waypoint *waypointp) fprintf(ofd, "\n"); } -void +static void geo_write(void) { fprintf(ofd, "\n"); @@ -206,5 +218,6 @@ ff_vecs_t geo_vecs = { geo_read, geo_write, NULL, - geo_args + geo_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/geoniche.c b/geoniche.c index b0c85be65..7be79803c 100644 --- a/geoniche.c +++ b/geoniche.c @@ -2,6 +2,7 @@ Read and write GeoNiche files. Copyright (C) 2003 Rick Richardson + Copyright (C) 2006 Robert Lipe This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,13 +21,22 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" +#include "jeeps/gpsmath.h" +#include "garmin_tables.h" + +#include +#include #define MYNAME "Geoniche" -#define MYTYPE 0x50454e44 /* PEND */ +#define MYTYPE_ASC 0x50454e44 /* PEND */ +#define MYTYPE_BIN 0x44415441 /* DATA */ #define MYCREATOR 0x47656f4e /* GeoN */ +#undef GEONICHE_DBG + static FILE *FileIn; static FILE *FileOut; static const char *FilenameOut; @@ -40,10 +50,10 @@ static char *Arg_category = NULL; static arglist_t Args[] = { {"dbname", &Arg_dbname, - "Database name (filename)", NULL, ARGTYPE_STRING }, + "Database name (filename)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, {"category", &Arg_category, - "Category name (Cache)", NULL, ARGTYPE_STRING }, - {0, 0, 0, 0, 0 } + "Category name (Cache)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define ARG_FREE(X) do { if (X) { xfree(X); X = NULL; } } while (0) @@ -180,17 +190,10 @@ eof: } static void -data_read(void) +geoniche_read_asc(const struct pdb *pdb) { - struct pdb *pdb; struct pdb_record *pdb_rec; - if (NULL == (pdb = pdb_Read(fileno(FileIn)))) - fatal(MYNAME ": pdb_Read failed\n"); - - if ((pdb->creator != MYCREATOR) || (pdb->type != MYTYPE)) - fatal(MYNAME ": Not a GeoNiche file.\n"); - /* Process record 0 */ pdb_rec = pdb->rec_index.rec; if (strcmp((char *) pdb_rec->data, Rec0Magic)) @@ -214,7 +217,9 @@ data_read(void) int icon; char *notes; char gid[6+1]; - struct tm tm = {0}; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); wpt = waypt_new(); if (!wpt) @@ -224,7 +229,7 @@ data_read(void) /* Field 1: Target */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 1.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 1 (target).\n"); if (strcmp(p, "Route") == 0) fatal(MYNAME ": Route record type is not implemented.\n"); if (strcmp(p, "Target")) @@ -233,100 +238,102 @@ data_read(void) /* Field 2: Import ID number */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 2.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 2 (ID).\n"); id = atoi(p); xfree(p); /* Field 3: Title */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 3.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 3 (Title).\n"); title = p; /* Field 4: Route ID number */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 4.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 4 (Route ID).\n"); route_id = atoi(p); xfree(p); /* Field 5: Category */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 5.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 5 (Category).\n"); category = p; /* Field 6: Latitude */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 6.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 6 (Latitude).\n"); lat = atof(p); xfree(p); /* Field 7: Longitude */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 7.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 7 (Longitude).\n"); lon = atof(p); xfree(p); /* Field 8: Altitude */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 8.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 8 (Altitude).\n"); alt = atof(p); xfree(p); /* Field 9: Creation date */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 9.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 9 (Creation date).\n"); datestr = p; /* Field 10: Creation time */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 10.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 10 (Creation time).\n"); timestr = p; /* Field 11: Visited date */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 11.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 11 (Visited date).\n"); xfree(p); /* Field 12: Visited time */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 12.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 12 (Visited time).\n"); xfree(p); /* Field 13: Icon color (R G B) */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 13.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 13 (Icon color).\n"); xfree(p); /* Field 14: icon number */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 14.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 14 (Icon number).\n"); icon = atoi(p); xfree(p); /* Field 15: unused */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 15.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 15 (unused1).\n"); xfree(p); /* Field 16: unused */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 16.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 16 (unused2).\n"); xfree(p); /* Field 17: unused */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 17.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 17 (unused3).\n"); xfree(p); /* Field 18: Notes */ p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 18.\n"); + if (!p) fatal(MYNAME ": Premature EOD processing field 18 (Notes).\n"); notes = p; sscanf(datestr, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year); tm.tm_mon -= 1; tm.tm_year -= 1900; sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - wpt->creation_time = mktime(&tm); + if (tm.tm_year >= 1970) { + wpt->creation_time = mktime(&tm); + } xfree(datestr); xfree(timestr); @@ -352,6 +359,183 @@ data_read(void) waypt_add(wpt); } +} + +static char *geoniche_icon_map[] = /* MPS */ +{ + /* 21 */ "Cross", + /* 22 */ "Cross (light)", + /* 23 */ "Cross (little)", + /* 24 */ "Cross (straight)", + /* 25 */ "Cross (light straight)", + /* 26 */ "Cross (little straight)", + /* 27 */ NULL, + /* 28 */ NULL, + /* 29 */ NULL, + /* 2A */ "Flag", + /* 2B */ "Car", /* 56 */ + /* 2C */ "Gas Station", /* 8 */ + /* 2D */ "Observation Point", + /* 2E */ "Scenic Area", /* 48 */ + /* 2F */ "City", + /* 30 */ "Mountains", + /* 31 */ "Park", /* 46 */ + /* 32 */ "Forest", /* 105 */ + /* 33 */ "Campground", /* 38 */ + /* 34 */ NULL, + /* 35 */ "Men", + /* 36 */ "Woman", + /* 37 */ "Hotel", /* 59 */ + /* 38 */ "Residence", /* 10 */ + /* 39 */ "Restaurant", /* 11 */ + /* 3A */ "Cafe", + /* 3B */ NULL, + /* 3C */ "Airport", /* 107 */ + /* 3D */ "Medical Facility", /* 43 */ + /* 3E */ "Ropeway", + /* 3F */ "Sailing Area", + /* 40 */ "Anchor", + /* 41 */ NULL, /* Half Anchor ??? */ + /* 42 */ "Fishing Area", /* 7 */ + /* 43 */ "Stop Sign", + /* 44 */ "Question Sign", + /* 45 */ NULL, + /* 46 */ NULL, + /* 47 */ "Euro Sign", + /* 48 */ "Bank", /* 6 */ + /* 49 */ NULL, + /* 4A */ "Left Arrow", + /* 4B */ "Right Arrow", + /* 4C */ "Traditional Cache", + /* 4D */ "Multi-Cache", /* 86 */ + /* 4E */ "Virtual Cache", /* 48 */ + /* 4F */ "Letterbox Cache", + /* 50 */ "Event Cache", /* 47 */ + /* 51 */ "Webcam Cache", /* 90 */ + /* 52 */ "Mystery or puzzle Cache", +}; + +static char * +geoniche_icon_to_descr(const int no) +{ + char *result = NULL; + + if (no >= 0x21) + { + int i = no - 0x21; + if (i <= 49) + { + result = geoniche_icon_map[i]; + } + } + if (result != NULL) + { + result = xstrdup(result); + } + return result; +} + +static void +geoniche_read_bin(const struct pdb *pdb) +{ + struct pdb_record *pdb_rec; + + /* Process records */ + + for (pdb_rec = pdb->rec_index.rec; pdb_rec != NULL; pdb_rec = pdb_rec->next) + { + char *vdata = (char *) pdb_rec->data; + struct tm created, visited; + int icon_nr, selected; + int latdeg, londeg; + double lat, lon, altitude; + waypoint *waypt; + + memset(&visited, 0, sizeof(visited)); + memset(&created, 0, sizeof(created)); + + latdeg = be_read16(vdata + 0); + lat = be_read32(vdata + 2); + londeg = be_read16(vdata + 6); + lon = be_read32(vdata + 8); + altitude = (float) be_read32(vdata + 12); + selected = vdata[16]; + created.tm_min = be_read16(vdata + 20); + created.tm_hour = be_read16(vdata + 22); + created.tm_mday = be_read16(vdata + 24); + created.tm_mon = be_read16(vdata + 26); + created.tm_year = be_read16(vdata + 28); + visited.tm_min = be_read16(vdata + 34); + visited.tm_hour = be_read16(vdata + 36); + visited.tm_mday = be_read16(vdata + 38); + visited.tm_mon = be_read16(vdata + 40); + visited.tm_year = be_read16(vdata + 42); + +#ifdef GEONICHE_DBG + printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", + created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, + visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); +#endif + icon_nr = vdata[62]; + + latdeg = 89 - latdeg; + lat = lat * (double) 0.0000006; + if (latdeg >= 0) + lat = (double) 60.0 - lat; + else + latdeg++; + + lon = lon * (double) 0.0000006; + while (londeg >= 360) londeg-=360; + if (londeg > 180) + { + lon = (double) 60.0 - lon; + londeg = londeg - 359; + } + + created.tm_year-=1900; + created.tm_mon--; + + waypt = waypt_new(); + + waypt->shortname = xstrdup(vdata + 63); + waypt->altitude = altitude; + waypt->creation_time = mkgmtime(&created); + + GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); + GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); + + waypt->icon_descr = geoniche_icon_to_descr(icon_nr); + if (waypt->icon_descr != NULL) + waypt->wpt_flags.icon_descr_is_dynamic = 1; + + waypt_add(waypt); + } +} + +static void +data_read(void) +{ + struct pdb *pdb; + + if (NULL == (pdb = pdb_Read(fileno(FileIn)))) + fatal(MYNAME ": pdb_Read failed\n"); + + if (pdb->creator != MYCREATOR) + fatal(MYNAME ": Not a GeoNiche file.\n"); + + switch(pdb->type) + { + case MYTYPE_ASC: + geoniche_read_asc(pdb); + break; + case MYTYPE_BIN: + geoniche_read_bin(pdb); + break; + default: + fatal(MYNAME ": Unsupported GeoNiche file.\n"); + } + free_pdb(pdb); } @@ -369,9 +553,24 @@ enscape(char *s) buf = d = xmalloc(strlen(s) * 2 + 1); for (; *s; ++s) { - if (*s == '\\' || *s == ',') + +/* + * 3 May 06: need to escape single quotes for v1.40 release + */ + + if (*s == '\\' || *s == ',' || *s == '\'') + { *d++ = '\\'; - *d++ = *s; + *d++ = *s; + } + +/* 3 May 06: stop stripping for better readability + * + * else if ((*s == '\r') || (*s == '\n')) + * *d++ = ' '; + */ + else + *d++ = *s; } *d = 0; @@ -398,11 +597,74 @@ wpt2icon(const waypoint *wpt) else if (strstr(desc, "hyb")) return 47; else if (strstr(desc, "unk")) return 48; else if (strstr(desc, "cam")) return 49; - else return 0; + + switch (wpt->gc_data.type) { + case gt_traditional: return 43; + case gt_multi: return 44; + case gt_locationless: return 45; + case gt_earth: return 45; + case gt_virtual: return 45; + case gt_letterbox: return 46; + case gt_event: return 47; + case gt_cito: return 47; + case gt_suprise: return 48; + case gt_webcam: return 49; + case gt_unknown: return 0; + case gt_benchmark: return 0; + case gt_ape: return 0; + case gt_mega: return 0; + } + + return 0; +} + +static char * +geoniche_geostuff(const waypoint *wpt) +{ + char *gs = NULL, *tmp1, *tmp2, *tmp3; + char tbuf[10240]; + + if (!wpt->gc_data.terr) { + return NULL; + } + + snprintf(tbuf, sizeof(tbuf), "\n%s by %s\n\n", gs_get_cachetype(wpt->gc_data.type), wpt->gc_data.placer); + gs = xstrappend(gs, tbuf); + +/* + * 3 May 06: Removed duplicated information + * + * snprintf(tbuf, sizeof(tbuf), "Waypoint: %s %s\n", wpt->shortname, wpt->description); + * gs = xstrappend(gs, tbuf); + */ + +/* + * 3 May 06: Added container type + */ + snprintf(tbuf, sizeof(tbuf), "Container: %s\nDifficulty: %3.1f\nTerrain: %3.1f\n\n", gs_get_container(wpt->gc_data.container), wpt->gc_data.diff/10.0, wpt->gc_data.terr/10.0); + gs = xstrappend(gs, tbuf); + + tmp1 = strip_html(&wpt->gc_data.desc_short); + tmp2 = strip_html(&wpt->gc_data.desc_long); + gs = xstrappend(gs, tmp1); + gs = xstrappend(gs, tmp2); + + tmp3 = rot13(wpt->gc_data.hint); + snprintf(tbuf, sizeof(tbuf), "\n\nHint: %s\n", tmp3); + gs = xstrappend(gs, tbuf); + + xfree(tmp1); + xfree(tmp2); + xfree(tmp3); + + tmp1 = enscape(gs); + xfree(gs); + + return tmp1; } static void -copilot_writewpt(const waypoint *wpt) +geoniche_writewpt(const waypoint *wpt) { static int ct = 0; struct pdb_record *opdb_rec; @@ -415,6 +677,8 @@ copilot_writewpt(const waypoint *wpt) char timestr[8+1]; char *notes; int id; + time_t tx; + char *gs; if (ct == 0) { @@ -425,7 +689,7 @@ copilot_writewpt(const waypoint *wpt) fatal(MYNAME ": libpdb couldn't append record\n"); } - if (wpt->description[0]) + if ( wpt->description && wpt->description[0] ) title = enscape(wpt->description); else title = enscape(wpt->shortname); @@ -433,16 +697,31 @@ copilot_writewpt(const waypoint *wpt) id = gid2id(wpt->shortname); if (id < 0) id = ct; - - tm = *localtime(&wpt->creation_time); - strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); - strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + + tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; + if (tx == 0) { /* maybe zero during testo (freezed time) */ + strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ + strcpy(timestr, "00:00:00"); + } + else { + tm = *localtime(&tx); + strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); + strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + } /* Notes field MUST have soemthing in it */ if (!wpt->notes || wpt->notes[0] == 0) notes = xstrdup(title); else notes = enscape(wpt->notes); + + gs = geoniche_geostuff(wpt); + if (gs) { + notes = xstrappend(notes, gs); + xfree (gs); + } + /* last chance to fill notes with something */ + if (*notes == '\0') notes = xstrappend(notes, "(notes)"); vdata = (ubyte *) xmalloc(vsize); if (vdata == NULL) @@ -502,20 +781,23 @@ data_write(void) if (NULL == (PdbOut = new_pdb())) fatal (MYNAME ": new_pdb failed\n"); - if (Arg_dbname) + if (Arg_dbname) { + if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) + fatal(MYNAME ": Reserved database name!\n"); strncpy(PdbOut->name, Arg_dbname, PDB_DBNAMELEN); + } else strncpy(PdbOut->name, FilenameOut, PDB_DBNAMELEN); PdbOut->name[PDB_DBNAMELEN-1] = 0; PdbOut->attributes = PDB_ATTR_BACKUP; PdbOut->ctime = PdbOut->mtime = current_time() + (49*365 + 17*366) * (60*60*24); - PdbOut->type = MYTYPE; + PdbOut->type = MYTYPE_ASC; PdbOut->creator = MYCREATOR; PdbOut->version = 0; PdbOut->modnum = 1; - waypt_disp_all(copilot_writewpt); + waypt_disp_all(geoniche_writewpt); pdb_Write(PdbOut, fileno(FileOut)); @@ -534,5 +816,7 @@ ff_vecs_t geoniche_vecs = data_read, data_write, NULL, - Args + Args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; +#endif diff --git a/globals.c b/globals.c new file mode 100644 index 000000000..72e343d3a --- /dev/null +++ b/globals.c @@ -0,0 +1,29 @@ +/* + Global data for GPSBabel. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include "defs.h" + +global_options global_opts; +const char gpsbabel_version[] = VERSION; +time_t gpsbabel_now; /* gpsbabel startup-time; initialized in main.c with time() */ +time_t gpsbabel_time; /* gpsbabel startup-time; initialized in main.c with current_time(), ! ZERO within testo ! */ + diff --git a/glogbook.c b/glogbook.c index 8b15a6856..711d1225b 100644 --- a/glogbook.c +++ b/glogbook.c @@ -31,7 +31,7 @@ static route_head *trk_head; static arglist_t glogbook_args[] = { - {0, 0, 0, 0, 0} + ARG_TERMINATOR }; /* Tracks */ @@ -54,31 +54,31 @@ static xg_tag_mapping gl_map[] = { { NULL, 0, NULL} }; -void +static void glogbook_rd_init(const char *fname) { xml_init(fname, gl_map, NULL); } -void +static void glogbook_read(void) { xml_read(); } -void +static void glogbook_rd_deinit(void) { xml_deinit(); } -void +static void glogbook_wr_init(const char *fname) { ofd = xfopen(fname, "w", MYNAME); } -void +static void glogbook_wr_deinit(void) { fclose(ofd); @@ -100,19 +100,19 @@ glogbook_waypt_pr(const waypoint *wpt) fprintf(ofd, " \n"); } -void +static void glogbook_hdr( const route_head *rte) { fprintf(ofd, " \n"); } -void +static void glogbook_ftr(const route_head *rte) { fprintf(ofd, " \n"); } -void +static void glogbook_write(void) { fprintf(ofd, "\n"); @@ -142,7 +142,7 @@ void gl_trk_pnt_s(const char *args, const char **unused) void gl_trk_pnt_e(const char *args, const char **unused) { - route_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } void gl_trk_utc(const char *args, const char **unused) @@ -169,7 +169,7 @@ void gl_trk_alt(const char *args, const char **unused) ff_vecs_t glogbook_vecs = { ff_type_file, - FF_CAP_RW_ALL, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none}, glogbook_rd_init, glogbook_wr_init, glogbook_rd_deinit, @@ -177,6 +177,6 @@ ff_vecs_t glogbook_vecs = { glogbook_read, glogbook_write, NULL, - glogbook_args + glogbook_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; - diff --git a/google.c b/google.c index ab09b35cc..6ff6a8f59 100644 --- a/google.c +++ b/google.c @@ -22,28 +22,30 @@ static char *encoded_points = NULL; static char *encoded_levels = NULL; static char *script = NULL; - -FILE *fd; +static route_head *routehead; +static short_handle desc_handle; static int serial = 0; #define MYNAME "google" #define MY_CBUF 4096 -#if NO_EXPAT -void +#if ! HAVE_LIBEXPAT +static void google_rd_init(const char *fname) { fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n"); } -void +static void google_read(void) { } #else static xg_callback goog_points, goog_levels, goog_poly_e, goog_script; +static xg_callback goog_segment_s, goog_segment, goog_td_s, goog_td_b; +static xg_callback goog_td_e; static xg_tag_mapping google_map[] = { @@ -51,6 +53,11 @@ xg_tag_mapping google_map[] = { { goog_levels, cb_cdata, "/page/directions/polyline/levels" }, { goog_poly_e, cb_end, "/page/directions/polyline" }, { goog_script, cb_cdata, "/html/head/script" }, + { goog_segment_s, cb_start, "/page/directions/segments/segment" }, + { goog_segment, cb_cdata, "/page/directions/segments/segment" }, + { goog_td_s, cb_start, "/div/table/tr/td" }, + { goog_td_b, cb_cdata, "/div/table/tr/td/b" }, + { goog_td_e, cb_end, "/div/table/tr/td" }, { NULL, 0, NULL } }; @@ -99,11 +106,85 @@ void goog_levels( const char *args, const char **unused ) } } +static char goog_segname[7]; +static char *goog_realname = NULL; + +/* + * The segments contain an index into the points array. We use that + * index to find the waypoint and insert a better name for it. + */ +void goog_segment_s( const char *args, const char **attrv ) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "pointIndex")) { + snprintf(goog_segname, sizeof(goog_segname), "\\%5.5x", atoi(avp[1])); + } + avp += 2; + } + +} + +void goog_segment( const char *args, const char **unused ) +{ + waypoint *wpt_tmp; + + wpt_tmp = route_find_waypt_by_name( routehead, goog_segname); + if (wpt_tmp) { + xfree(wpt_tmp->shortname); + wpt_tmp->shortname = mkshort(desc_handle,args); + wpt_tmp->description = xstrdup(args); + } +} + +void goog_td_s( const char *args, const char **attrv ) +{ + const char **avp = &attrv[0]; + int isdesc = 0; + while (*avp) { + if ( 0 == strcmp(avp[0], "class" )) { + isdesc = !strcmp(avp[1], "desc" ); + } + else if ( isdesc && (0 == strcmp( avp[0], "id" ))) { + snprintf( goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(avp[1] + 6 )); + } + avp += 2; + } +} + +void goog_td_b( const char *args, const char **attrv ) { + if ( goog_segname[0] == '\\' && !strchr( args, '\xa0')) { + if ( goog_realname ) { + xfree( goog_realname ); + goog_realname = NULL; + } + goog_realname = xmalloc( strlen(args)+1); + strcpy( goog_realname, args ); + } +} +void goog_td_e( const char *args, const char **attrv ) +{ + if ( goog_segname[0] == '\\' && goog_realname ) { + goog_segment( goog_realname, attrv ); + } + goog_segname[0] = '\0'; + if ( goog_realname ) { + xfree( goog_realname ); + goog_realname = NULL; + } +} + static long decode_goog64( char **str ) { long result = 0; unsigned char c = 0; unsigned char shift = 0; + + if ( !(**str)) { + return 0; + } do { @@ -128,9 +209,9 @@ void goog_poly_e( const char *args, const char **unused ) long level2 = -9999; char *str = encoded_points; char *lstr = encoded_levels; - - route_head *track_head = route_head_alloc(); - route_add_head(track_head); + + routehead = route_head_alloc(); + route_add_head(routehead); while ( str && *str ) { @@ -160,55 +241,119 @@ void goog_poly_e( const char *args, const char **unused ) wpt_tmp->route_priority=level; wpt_tmp->shortname = (char *) xmalloc(7); sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); - route_add_wpt(track_head, wpt_tmp); + route_add_wpt(routehead, wpt_tmp); } } - if ( encoded_points ) - { - xfree( encoded_points ); - encoded_points = NULL; - } - if ( encoded_levels ) - { - xfree( encoded_levels ); - encoded_levels = NULL; - } } -void +static void google_rd_init(const char *fname) { + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 12); + xml_init(fname, google_map, "ISO-8859-1" ); } -void +static void google_read(void) { xml_read(); + if ( encoded_points ) + { + xfree( encoded_points ); + encoded_points = NULL; + } + if ( encoded_levels ) + { + xfree( encoded_levels ); + encoded_levels = NULL; + } if ( script ) { char *xml = strchr( script, '\'' ); + char *dict = strstr( script, "({" ); + char *end = NULL; - if ( xml ) { + + if ( xml && (!dict || (xml < dict ))) { xml++; - end = strrchr( xml, '\'' ); + end = strchr( xml+1, '\'' ); if ( end ) { *end = '\0'; xml_deinit(); xml_init( NULL, google_map, NULL ); xml_readstring( xml ); + if ( encoded_points ) + { + xfree( encoded_points ); + encoded_points = NULL; + } + if ( encoded_levels ) + { + xfree( encoded_levels ); + encoded_levels = NULL; + } } } + else if ( dict ) { + char *panel = strstr( dict, "panel: '" ); + encoded_points = strstr( dict, "points: '" ); + encoded_levels = strstr( dict, "levels: '" ); + + if ( encoded_points && encoded_levels ) { + encoded_points += 9; + encoded_levels += 9; + end = strchr( encoded_points, '\'' ); + if ( end ) { + *end = '\0'; + end = encoded_points; + while ( (end = strstr(end, "\\\\" ))) { + memmove( end, end+1, strlen(end)+1 ); + end++; + } + end = strchr( encoded_levels, '\'' ); + if ( end ) { + *end = '\0'; + end = encoded_levels; + while ( (end = strstr(end, "\\\\" ))) { + memmove( end, end+1, strlen(end)+1 ); + end++; + } + goog_poly_e( NULL, NULL ); + } + } + } + if ( panel ) { + panel += 8; + end = strstr( panel, "/table>
"); + end = panel; + while ( (end = strstr( end, "\\\"" ))) { + memmove( end, end+1, strlen(end)+1 ); + } + end = panel; + while ( (end = strstr( end, "\\'" ))) { + memmove( end, end+1, strlen(end)+1 ); + } + xml_deinit(); + xml_init( NULL, google_map, NULL ); + xml_readstring( panel ); + } + } + } xfree( script ); } } #endif -void +static void google_rd_deinit(void) { xml_deinit(); + mkshort_del_handle(&desc_handle); } ff_vecs_t google_vecs = { @@ -221,5 +366,6 @@ ff_vecs_t google_vecs = { google_read, NULL, NULL, - NULL + NULL, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ }; diff --git a/gpilots.c b/gpilots.c index 6af407510..b59e2a409 100644 --- a/gpilots.c +++ b/gpilots.c @@ -20,6 +20,7 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" #include "garmin_tables.h" @@ -153,15 +154,15 @@ struct record static FILE *file_in; static FILE *file_out; static const char *out_fname; -struct pdb *opdb; -struct pdb_record *opdb_rec; +static struct pdb *opdb; +static struct pdb_record *opdb_rec; static char *dbname = NULL; static arglist_t my_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING}, - {0, 0, 0, 0, 0} + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static void @@ -203,7 +204,7 @@ data_read(void) struct record *rec; struct pdb *pdb; struct pdb_record *pdb_rec; - route_head *track_head; + route_head *track_head = NULL; if (NULL == (pdb = pdb_Read(fileno(file_in)))) { fatal(MYNAME ": pdb_Read failed\n"); @@ -278,7 +279,7 @@ data_read(void) fi.i = le_read32(&rec->wpt.d108.dist); wpt_tmp->proximity = fi.f; wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0; - wpt_tmp->icon_descr = mps_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX); + wpt_tmp->icon_descr = gt_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX, NULL); waypt_add(wpt_tmp); break; @@ -333,7 +334,7 @@ data_read(void) wpt_tmp->creation_time = be_read32(&tp_cust->time) + 631065600; fi.i = be_read32(&tp_cust->alt); wpt_tmp->altitude = fi.f; - route_add_wpt(track_head, wpt_tmp); + track_add_wpt(track_head, wpt_tmp); tp_cust++; } break; @@ -364,7 +365,7 @@ data_read(void) lat = be_read32(&tp_comp->lat); wpt_tmp->longitude = lon / 2147483648.0 * 180.0; wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - route_add_wpt(track_head, wpt_tmp); + track_add_wpt(track_head, wpt_tmp); tp_comp++; } break; @@ -457,5 +458,7 @@ ff_vecs_t gpilots_vecs = { data_read, data_write, NULL, - my_args + my_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/gpsbabel-sample.ini b/gpsbabel-sample.ini new file mode 100644 index 000000000..743e9d704 --- /dev/null +++ b/gpsbabel-sample.ini @@ -0,0 +1,35 @@ +;------------------------------------------------------------------ +[Common format settings] +# snlen = 6 + +;------------------------------------------------------------------ +[Common filter settings] + +;------------------------------------------------------------------ +[Garmin categories] +; any # from 1 to 16 + +1 = Biker Stuff +2 = Slow food +3 = Fast food +16 = Fixed + +;------------------------------------------------------------------ +[ garmin_txt ] +Date = DD.MM.YYYY +Time = HH:mm:ss XX +Dist = M +Temp = C +Prec = 6 + +[ gdb ] +via = 1 + +;------------------------------------------------------------------ +[ tiger ] +snlen=7 + +;------------------------------------------------------------------ +[pathaway] +# dbname = The Last Trip +deficon = Golf Course diff --git a/gpsbabel.html b/gpsbabel.html new file mode 100644 index 000000000..af188eba0 --- /dev/null +++ b/gpsbabel.html @@ -0,0 +1,4371 @@ + + +GPSBabel Documentation

GPSBabel Documentation


Table of Contents

Introduction
The Problem
The Solution
1. Getting it and Building it
2. Usage
Invocation
Advanced Usage
Route and Track Modes
Working with predefined options
Realtime tracking
Batch mode (command files)
3. The Formats
? Character Separated Values (xcsv)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
EasyGPS binary format (easygps)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2006 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom POI file (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
Vito Navigator II tracks (vitosmt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary file format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Yahoo Geocode API data (yahoo)
4. Data Filters
Include Only Points Inside Polygon (polygon)
Include Only Points Within Distance of Arc (arc)
Include Only Points Within Radius (radius)
Interpolate between trackpoints (interpolate)
Manipulate track lists (track)
Rearrange waypoints by resorting (sort)
Remove all waypoints, tracks, or routes (nuketypes)
Remove Duplicates (duplicate)
Remove Points Within Distance (position)
Remove unreliable points with high hdop or vdop (discard)
Reverse stops within routes (reverse)
Save and restore waypoint lists (stack)
Simplify routes (simplify)
Transformate waypoints into a route, tracks into routes, ... (transform)
A. Supported Datums
B. Garmin Icons
C. GPSBabel XCSV Style Files
Introduction
Style file overview
Internal Constants
Global Properties of the File
GPSBabel Behavior Directives
Defining the Layout of the File
Defining Fields Within the File
Examples
Miscellaneous Notes

Introduction

Table of Contents

The Problem
The Solution

The Problem

There are simply too many gratuitously different file formats +to hold waypoint, track, and route information in various programs +used by computers and GPS receivers. +GPX defines a +standard in XML to contain all the data, but there are too many +programs that don't understand it yet and too much data that are in an +alternate formats. +

The Solution

I needed to convert waypoints between a couple of formats, so I +whipped up a converter and based it on an extensible foundation so +that it was easy to add new formats. Most file formats added so far +have taken under 200 lines of reasonable ISO C so they can be stamped +out pretty trivially. Formats that are ASCII text delimited in some +fixed way can be added with no programming at all via our 'style' +mechanism. +

Chapter 1. Getting it and Building it

+GPSBabel is distributed "ready to run" on most common +operating systems via the +download page. +

As GPSBabel runs on a wide variety of operating systems, +be sure to visit the +OS-Specific notes for +additional information. +

+ For operating systems where no binary is provided or if +you want the latest development version, you will have to build it from +source. The code should be compilable on any system with +ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, +Linux, Solaris, and a variety of processors and compilers. +

+ In most cases, the code is as simple to build as running: +

./configure && make

+

Expat +is strongly recommended for source builds as it is +required for reading all the XML formats such as GPX. +

libusb +is recommended for OS/X and Linux if you want to use a USB Garmin. +

There are additional flags that can be passed to configure to + customize your build of GPSBabel.

 ./configure --help

lists all the supported options, but additionally we have: +

+ --disable-shapefile Excludes the shapefile support. +

+ --disable-pdb Excludes the Palm database support and all formats that rely on it. +

+ --disable-csv Excludes all support for our something-separated formats. +

+ --disable-filters Excludes all filter support. +

+ --enable-efence Activate debugging mode for gpsbabel-debug. +

+ --with-doc=dir Specify that the doc should be created and installed in dir. +

+ --without-libusb Disables use of libusb, even it's it's available. +

+ --with-zlib=(included)|system|no By default, we use our own version of zlib. If you specify system the system zlib is used. A value of no (or --without-zlib) disables zlib. +

Chapter 2. Usage

Invocation

Invocation was meant to be flexible. Unfortunately, + that can sometimes lead to unwieldy command lines.

+If you're using GPSBabel, you will need to know how to do at least two things: +read data from a file, and write it to another file. There are four basic +commands you need to know to do those things: +

CommandMeaning
-i formatSet input format
-f filenameRead file
-o formatSet output format
-F filenameWrite output File

+The format parameters in the above list +refer to the names of formats or file types supported by GPSBabel. +

gpsbabel -? 

will always show you the supported file types. In this document, the +various supported formats are listed in Chapter 3, The Formats. The +name that you would use on the command line follows the format name in +parentheses. +

+The filename parameters specify the +name of a file to be read or written. +

To use + this program, just tell it what you're reading, where to read + it from, what you're writing, and what to write it to. For + example:

gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx

tells it to read the file "/tmp/geocaching.loc" in geocaching.com + format and create a new file in GPX format.

This command will read from a Magellan unit attached + to the first serial port on a Linux system (device names will + vary on other OSes) and write them as a geocaching loc file. + The second command does the same on Microsoft Windows.

gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc
gpsbabel -i magellan -f com1 -o geo -F mag.loc

Optionally, you may specify "-s" in any command line. This + causes the program to ignore any "short" names that may be + present in the source data format and synthesize one from the + long name. This is particularly useful if you're writing to + a target format that isn't the lowest common denominator but + the source data was written for the lowest common + denominator. I use this for writing data from geocaching.com + to my Magellan so my waypoints have "real" names instead of + the 'GC1234' ones that are optimized for NMEA-only receivers. + A geocacher with a Magellan receiver may thus find commands + like this useful.

 gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0  
 gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1

Advanced Usage

Argument are processed in the order they appear on the command +line and are translated internally into a pipeline that data flows +through when executed. Normally one would:

read from one input
optionally apply filters
write into one output

but GPSBabel is flexible enough to allow more complicated +operations such as reading from several files (potentially of +different types), applying a filter, reading more data, then write the +merged data to multiple destinations. +

The input file type remains unchanged until a new + -i argument is seen. + Files are read in the order they appear. So you could merge + three input files into one output file with:

gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc

You can merge files of different types:

gpsbabel  -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx \ 
+-o gpsutil -F big.gps

You can write the same data in different output formats:

gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt

If you want to change the character set of input or/and + output side you can do this with the option -c + <character set>. You can get a complete list + of supported character sets with "gpsbabel -l". To change + the character set on both sides you should do this:

gpsbabel -i xcsv,style=foo.style -c latin1 -f foo  \
+	         -o xcsv,style=bar.style -c ms-ansi -F bar

Note, that some formats has a fixed character set and ignore this option.

Route and Track Modes

Most formats will make reasonable attempt to work + transparently with waypoints, tracks, and routes. Some + formats, like 'garmin' and 'magellan' require the -t flag to work with tracks and + -r to work with + routes. -w is for + waypoints, and is the default. So if you wanted to read all + data from your unit into a gpx file, you might use a command + like:

 gpsbabel -t -r -w -i magellan -f com1:  -o gpx -F backup.gpx

Tracks and routes are advanced features and don't try + to handle every possible hazard that can be encountered + during a conversion. If you're merging or converting files + of similar limitations, things work very well.

Tracks and routes will sometimes be converted to a + list of waypoints when necessary, f.i. when writing into one + of the CSV formats. The inverse operation is not supported + right now, so reading the converted track back from CSV will + always result in a list of waypoints, not the original track. +

The presence of -s on the command line tends to + creats havoc on tracks and routes since many of these formats + rely on internal linkages between such points and renaming + them may break those linkages. In general, don't use + -s when tracks or + routes are present. +

Working with predefined options

+ GPSBabel can read a file on startup to set defaults for options. All + module and filter options may be set this way. +

+ The format of the file is identical to the inifile-format often seen + on Windows. Here is an example: +

[Common format settings]
snupper=Y
snlen=10
[gpx]
gpxver=1.1
[magellan]
baud=115200
[tiger]
[Garmin categories]
; any # from 1 to 16
1=fixed waypoints
2=temporary waypoints

+ Each section of the file starts with a '[section]' header followed by any + number of lines formatted option=value. Leading and trailing whitespace + will be + automatically removed from header, option and value items. + + Lines starting + with '#' or ';' will be treated as comments and ignored. +

+ There are three optional sections. +

  • "Common format settings"

    Any option from any of the formats listed here will be used by + GPSBabel unless explictly provided on the command line. +

  • "Common filter settings"

    As above, but for filters.

  • Garmin categories

    This allows you to give readable names to the numeric categories + used internally in some Garmin devices and the Mapsource formats + such as GDB and MPS. This is information is also used by our GPX + and garmin_txt formats as well.

+

+ By default, GPSBabel tries at startup to load the file named + gpsbabel.ini from the following locations: +

  • current working directory

  • Windows: all paths "APPDATA", "WINDIR", "SYSTEMROOT" declared in environment.

  • Unix like OS'ses: ${HOME}/.gpsbabel/, /usr/local/etc/ and /etc/

+ If the -p option is specified, the above locations are not searched. + Only the filename specified by that option will be used. +

+ There may be situations where predefined values are not useable + (i.e. wrapper applications using GPSBabel in the background). + The inifile mechanism can be disabled with an empty filename. +

gpsbabel -p "" -i gpx -f something.gpx -o tiger -F -

Realtime tracking

+ Introduced in GPSBabel 1.3.1, we now have an experimental feature for realtime tracking via the new '-T' option. This reads position reports from selected formats and writes an output file when a position report is received. +

+ As of this writing, Garmin's PVT protocol and NMEA are supported + inputs and KML is supported on output. Additional formats + may be added by interested parties later. +

+

gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml

+ Will read the USB-connected Garmin and rewrite 'xxx.kml' atomically, + suitable for a self-refreshing network link in Google Earth. +

Batch mode (command files)

+ In addition to reading arguments from the command line, GPSBabel can + read directions from batch (or command) files via the '-b' option. +

+ These files are ideal for holding long command lines, long file lists, complex filters + and so on. You can use all GPSBabel options and combinations when writing + such files. Nesting batch files by using the '-b' option within a batch file is supported. +

+ Here is an example demonstrating segmenting a large command line + by placing the input and filtering directives in a file called 'all_my_files'. +

gpsbabel -b all_my_files -o gdb -F all_my_tracks.gdb

+

+ 'all_my_files' could look like this: +

-i gpx
-f saxony_in_summer_2004.gpx -f austria_2005.gpx
-i gdb
-f croatia_2006.gdb
-x nuketypes,waypoints,routes
-x track,pack,split,title="LOG # %Y%m%d"

Chapter 3. The Formats

Table of Contents

? Character Separated Values (xcsv)
All database fields on one tab-separated line (tabsep)
Brauniger IQ Series Barograph Download (baroiq)
Cambridge/Winpilot glider software (cambridge)
CarteSurTable data file (cst)
Cetus for Palm/OS (cetus)
CoastalExplorer XML (coastexp)
Comma separated values (csv)
CompeGPS data files (.wpt/.trk/.rte) (compegps)
CoPilot Flight Planner for Palm/OS (copilot)
cotoGPS for Palm/OS (coto)
Custom "Everything" Style (custom)
Dell Axim Navigation System (.gpb) file format (axim_gpb)
DeLorme .an1 (drawing) file (an1)
DeLorme GPL (gpl)
DeLorme Street Atlas Plus (saplus)
DeLorme Street Atlas Route (saroute)
DeLorme XMap HH Native .WPT (xmap)
DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)
DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)
EasyGPS binary format (easygps)
FAI/IGC Flight Recorder Data Format (igc)
Franson GPSGate Simulation (gpssim)
Fugawi (fugawi)
Garmin 301 Custom position and heartrate (garmin301)
Garmin Logbook XML (glogbook)
Garmin MapSource - gdb (gdb)
Garmin MapSource - mps (mapsource)
Garmin MapSource - txt (tab delimited) (garmin_txt)
Garmin PCX5 (pcx)
Garmin POI database (garmin_poi)
Garmin serial/USB protocol (garmin)
Garmin Training Centerxml (gtrnctr)
Geocaching.com .loc (geo)
GeocachingDB for Palm/OS (gcdb)
GEOnet Names Server (GNS) (geonet)
GeoNiche .pdb (geoniche)
Google Earth (Keyhole) Markup Language (kml)
Google Maps XML (google)
GpilotS (gpilots)
GPS TrackMaker (gtm)
GPSBabel arc filter file (arc)
GpsDrive Format (gpsdrive)
GpsDrive Format for Tracks (gpsdrivetrack)
GPSman (gpsman)
GPSPilot Tracker for Palm/OS (gpspilot)
gpsutil (gpsutil)
GPX XML (gpx)
HikeTech (hiketech)
Holux (gm-100) .wpo Format (holux)
HSA Endeavour Navigator export File (hsandv)
HTML Output (html)
IGN Rando track files (ignrando)
Kartex 5 Track File (ktf2)
Kartex 5 Waypoint File (kwf2)
KuDaTa PsiTrex text (psitrex)
Lowrance USR (lowranceusr)
Magellan Explorist Geocaching (maggeo)
Magellan Mapsend (mapsend)
Magellan NAV Companion for Palm/OS (magnav)
Magellan SD files (as for eXplorist) (magellanx)
Magellan SD files (as for Meridian) (magellan)
Magellan serial protocol (magellan)
Map&Guide 'TourExchangeFormat' XML (tef)
Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)
Mapopolis.com Mapconverter CSV (mapconverter)
MapTech Exchange Format (mxf)
Microsoft AutoRoute 2002 (pin/route reader) (msroute)
Microsoft Streets and Trips (pin/route reader) (msroute)
Microsoft Streets and Trips 2002-2006 (s_and_t)
Motorrad Routenplaner (Map&Guide) .bcr files (bcr)
MS PocketStreets 2002 Pushpin (psp)
National Geographic Topo .tpg (waypoints) (tpg)
National Geographic Topo 2.x .tpo (tpo2)
National Geographic Topo 3.x/4.x .tpo (tpo3)
Navicache.com XML (navicache)
Navigon Mobile Navigator .rte files (nmn4)
Navitrak DNA marker format (dna)
NetStumbler Summary File (text) (netstumbler)
NIMA/GNIS Geographic Names File (nima)
NMEA 0183 sentences (nmea)
OziExplorer (ozi)
PalmDoc Output (palmdoc)
PathAway Database for Palm/OS (pathaway)
Quovadis (quovadis)
See You flight analysis data (cup)
Sportsim track files (part of zipped .ssz files) (sportsim)
Suunto Trek Manager (STM) .sdf files (stmsdf)
Suunto Trek Manager (STM) WaypointPlus files (stmwpp)
Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)
Textual Output (text)
TomTom POI file (tomtom)
TopoMapPro Places File (tmpro)
TrackLogs digital mapping (.trl) (dmtlog)
U.S. Census Bureau Tiger Mapping Service (tiger)
Universal csv with field structure in first line (unicsv)
Vcard Output (for iPod) (vcard)
Vito Navigator II tracks (vitosmt)
WiFiFoFum 2.0 for PocketPC XML (wfff)
Wintec WBT-100/200 Binary file format (wbt-bin)
Wintec WBT-100/200 GPS Download (wbt)
Yahoo Geocode API data (yahoo)

? Character Separated Values (xcsv)

+ This format can... +

  • + read and write waypoints +

+

+This format is a very flexible module that can be used to read or write +nearly any plain-text record-based waypoint file. This flexibility is +achieved by combining this format with "style" files that describe the +format of the waypoint files. +

+There are several formats built in to GPSBabel that use the underlying xcsv +machinery. Each of those formats takes the same options as the xcsv format, +with the obvious exception of the style option. +Those formats are all based on style files that can be found in +the "style" directory in the GPSBabel source distribution. +

style option

+ Full path to XCSV style file. +

+This option specifies the style file that defines the records to be read on +input or written on output. This is not a valid option for the various +built-in xcsv-based styles; they have prebuilt style definitions. +

+For information on the format of xcsv style files, see +Appendix C, GPSBabel XCSV Style Files. +

snlen option

+ Max synthesized shortname length. +

+This option specifies the maximum allowable length for a short name on +output. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

snwhite option

+ Allow whitespace synth. shortnames. +

+When this option is specified, GPSBabel will allow whitespace (spaces or tabs) +in generated short names. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

snupper option

+ UPPERCASE synth. shortnames. +

+When this option is specified, GPSBabel will make all short names contain +only UPPERCASE characters. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

snunique option

+ Make synth. shortnames unique. +

+When this option is specified, GPSBabel will ensure that all short names are +unique within the output file. This option overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

urlbase option

+ Basename prepended to URL on output. +

+This option specifies the base name to prepend to a URL on output. This +might be useful if an input file contains URLs in a relative format and you +need them to be in an absolute format. +

prefer_shortnames option

+ Use shortname instead of description. +

+This option causes GPSBabel to use the short name of the waypoint instead +of the description. This overrides the style file. +

+Valid values for this option are 0 (off) and 1 (on). +

All database fields on one tab-separated line (tabsep)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+This format, like the custom format, is +mainly used for the purpose of testing GPSBabel. It is supposed to contain +one field for each piece of information supported by the +xcsv format writer, but it may not be entirely +in sync with the documentation at Appendix C, GPSBabel XCSV Style Files. +

+For a list of fields, see the style/tabsep.style file in the GPSBabel source +distribution. +

Brauniger IQ Series Barograph Download (baroiq)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

Serial download protocol for the Brauniger IQ series of +barograph recording flight instruments. This format creates a +track of altitude vs time which can be merged with a GPS track +of the same flight to create a three dimensional IGC file.

Cambridge/Winpilot glider software (cambridge)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Support for Cambridge/Winpilot flight analysis and planning software for + glider pilots.

CarteSurTable data file (cst)

+ This format can... +

  • + read waypoints +

  • + read tracks +

  • + read routes +

+

With this format we can read CarteSurTable data files. +CarteSurTable is a shareware program widely used in France. The data +inside have to be seen as a mixture of a waypoints list, one route and +several tracks. phgiraud.free.fr +

Cetus for Palm/OS (cetus)

+ This format can... +

  • + read and write waypoints +

  • + read tracks +

+

Cetus GPS www.cetusgps.dk is a program for +Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read +and write files for that program.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

appendicon option

+ Append icon_descr to description. +

+This option will add the icon description to the end of the waypoint +description on output. This can be useful if the icon is used to convey +important information about the waypoint. For example, the icon might be +"found geocache" or "unfound geocache"; it might be useful to know that when +looking at a list of icons in Cetus. +

CoastalExplorer XML (coastexp)

+ This format can... +

  • + read and write waypoints +

  • + read and write routes +

+

This is the format used by CoastalExplorer (tm). The +format is XML with items uniquely identified by Windows-style UUIDs. +http://www.rosepointnav.com +

Comma separated values (csv)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

There are a billion variants of Comma Separated Value +data. This is the one that makes Delorme S&A Deluxe 9 happy. It's +also a very simple program and useful for many other programs like +spreadsheets.

CSV is also the correct format for Lowrance MapCreate, +their commercial mapping program, or GDM6 (their free waypoint +manager) for iFinder which is available at lowrance.com +

CompeGPS data files (.wpt/.trk/.rte) (compegps)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+These data files are "character" separated text files like +the pcx format. "Character" means special data lines can have their +own separator. +

+Since release 6.1 of CompeGPS™, GPX is also a +supported import/export format for waypoints, routes and tracks. +

+For more information please have a look at +http://www.compegps.com +

deficon option

+ Default icon name. +

+This option specifies the default icon name on output. +

index option

+ Index of route/track to write (if more the one in source). +

+Because this format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o compegps,index=1 -F route1.txt -o compegps,index=2 -F route2.txt

radius option

+ Give points (waypoints/route points) a default radius (proximity). +

+This option specifies the default proximity for waypoints and route points. +

snlen option

+ Length of generated shortnames (default 16). +

+This option specifies the default length for short names generated on output. +The default length is 16. +

CoPilot Flight Planner for Palm/OS (copilot)

+ This format can... +

  • + read and write waypoints +

+

This code is mostly intended to convert CoPilot Flight +Planner for Palmd/OS atabases into other formats. You probably should +not use this to write CoPilot databases, although the code is there, +because GPSBabel doesn't convert magnetic declination values.

Questions, bug reports, etc, to ptomblin at +xcski.com

+ http://xcski.com/~ptomblin/CoPilot/ +and http://navaid.com/CoPilot +

cotoGPS for Palm/OS (coto)

+ This format can... +

  • + read and write waypoints +

  • + read tracks +

+

+This format supports cotoGPS™, a Palm GPS program. +It can read both track and marker (waypoint) files. It is currently unable +to write track files, so only marker files can be written. The marker +categories are written to and read from the icon description. The 'Not +Assigned' category leaves the icon description empty on read. +Currently geocache info is ignored. +

In addition to the documented options, this format also has a +debugging option called internals which takes an XCSV +delimiter value. It writes some internal values (distance, arc, x and y) +of the cotoGPS track format to the notes field. +

+Contributed by Tobias Minich. +

+cotoGPS +

zerocat option

+ Name of the 'unassigned' category. +

+This option specifies a name for the "Not Assigned" category in the Palm +database. The default is "Not Assigned". +

Custom "Everything" Style (custom)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+This format is not actually used by any real product. It is most useful +for debugging purposes when developing a new format module for GPSBabel. +

+To understand the contents of this file, look at the +style/custom.style file in the GPSBabel source +distribution as well as Appendix C, GPSBabel XCSV Style Files. +

Dell Axim Navigation System (.gpb) file format (axim_gpb)

+ This format can... +

  • + read tracks +

+

+ This format reads the binary (.gpb) track logs recorded on + Dell Axim Navigation Systems. +

+ This is a read-only format for now as the format was reverse + engineered and there are many unknown bytes. We can successfully + extract the common GPS data. +

DeLorme .an1 (drawing) file (an1)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+This format supports the DeLorme ".an1" drawing file format. It can +currently be used to either read or write drawing files. If you use +this format to create drawing files with routes or waypoints from another +source, by default it will create "Red Flag" symbols for waypoints, and +thick red lines for routes or tracks. It is possible to merge two drawing +layers by doing something like this: +

gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1

+In this case, the merged data will contain all of the +properties of the original data. +

type option

+ Type of .an1 file. +

This option specifies the type of the drawing layer +to be created. The supported values are "drawing", "road", "trail", +"waypoint", or "track". If you do not specify a type, the default +will be either the type of the previous an1 file or "drawing" if there +is no previous file. This lets you merge, for example, two road layers +without having to specify "type=road" for the output.

road option

+ Road type changes. +

+If you are creating a road layer, you may use the "road" option, which +allows you to change the types of roads based on their names. You can +change multiple roads at the same time. Currently supported types are +

+

TypeMeaning
limitedLimited-access freeways
tollLimited-access toll highways
rampAccess ramps for limited-access highways
usNational highways (e.g. US routes)
primaryPrimary State/Provincial routes
stateState/Provincial routes
majorMajor Connectors
ferryFerry Routes
localLocal Roads
editableUser-drawn Roads

+

+GPSBabel defaults to creating editable roads. These are routed just like +local roads, but may be edited with the drawing tools in Street Atlas. +

+This option has a special format that is best demonstrated by example: +

"road=I-599!limited!Beecher St.!major" 

+This option will cause any road named "I-599" to become a limited-access +highway and any road named "Beecher St." to become a major connector. Note +that roads that have had their types changed in this way are not editable +in Street Atlas, so make sure they are where you want them before you +change them, and make sure to keep a backup of your original road layer. +Note that the ! is a shell metacharacter in bash and possibly other shells, +so you may have to use single quotes or some other escape mechanism. +

+There is a tutorial on +how +to create an onramp for a limited access highway in Street Atlas USA +using GPSBabel. +

nogc option

+ Do not add geocache data to description. +

+If your original data contains geocaching-specific information such as +difficulty and terrain, GPSBabel will automatically include that information +in the waypoint descriptions in the generated drawing file. If you do not +want that, specify the "nogc" option on the command line: +

gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1

deficon option

+ Symbol to use for point data. +

+This option allows you to specify which symbol to use for points that +don't have a symbol already. It defaults to "Red Flag" but it accepts +any symbol name you can put in a DeLorme export file. To find the name +of a specific symbol in Street Atlas, let the mouse pointer hover over +it for a few seconds and the name will be displayed. +

color option

+ Color for lines or mapnotes. +

This option allows you to specify the color for +line or mapnote data. It accepts color names of the form "#FF0000" (red) or any +of the color names from the Cascading Style Sheets (CSS) +specification.

zoom option

+ Zoom level to reduce points. +

+This option specifies at what zoom level Street Atlas will begin showing +reduced versions of your symbols. The default is 10. Setting zoom to 0 will +disable this feature. Setting it to anything but the default will override +the zoom level specified on any waypoints that were read from an existing +an1 file; this is by design. +

wpt_type option

+ Waypoint type. +

+This option specifies how to represent point data in the draw file. +Valid waypoint types are "symbol", "text", "mapnote", "circle", and "image". +The default is "symbol". +

+If you specify a waypoint type of "image", you should make sure that the +icon descriptions of your waypoints are the full names, including drive letters +and full path, of image files in a format that works with your DeLorme +product. Note that this means that the .an1 file you generate will not work +on any computer that does not have those images in the same place; this is +part of the design of the an1 format and cannot be avoided. +

radius option

+ Radius for circles. +

+If the waypoint type is "circle", the "radius" option specifies +the radius of the circles. By default, this is in miles, but it may be +specified in kilometers by adding a 'k'. The default radius is 1/10 mile. +

DeLorme GPL (gpl)

+ This format can... +

  • + read and write tracks +

+

This is the 'gpl' format as used in Delorme mapping +products. It is a track format and contains little more than the +tracklog of a GPS that was attached while driving. frontiernet.net +

DeLorme Street Atlas Plus (saplus)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This format is for Street Atlas USA 2004 Plus. +

For geocachers importing data from a tool like GSAK or +Spinner, import the file twice in XData. One will create a file with +the Cache description as a hyperlink on the flag. This can clutter up +the screen and when you try to zoom in, it causes problems. So the +second one will only have a flag. Thus you can turn off and on which +one you want to view. The first time you import the file, in the +assign field types, check the circle above Full Name and then next. +The second time you import the file do not check any circle and in the +second to last column, change URL to none and then click next. Use the +same name you used the first time but add -Flag to it. +

DeLorme Street Atlas Route (saroute)

+ This format can... +

  • + read tracks +

+

+This format reads route files from many Delorme mapping products. +It supports the anr, rte, and rtd formats as either tracks or +routes.

All options only apply to route files from newer (anr) +versions of DeLorme software; older versions didn't store the turn +information with the route. +

turns_important option

+ Keep turns if simplify filter is used. +

This option only makes sense in +conjunction with the 'simplify' filter. It ensures that the route +simplification process will remove the points corresponding to turns +only after it has removed all other route points. +

turns_only option

+ Only read turns; skip all other points. +

This option causes GPSBabel to read only the +waypoints associated with named turns. This should create a list of +waypoints that correspond to the itinerary from Street Atlas.

split option

+ Split into multiple routes at turns. +

This option causes GPSBabel to create separate +routes for each street, creating a new route at each turn point. For +obvious reasons, 'split' cannot be used at the same time as the +'turns_only' or 'turns_important' options.

controls option

+ Read control points as waypoint/route/none. +

This option lets you read the control points +(start, end, vias, and stops) for your route as well as the route +itself. The default for this option is 'none', which won't read the +control points. You may also specify 'waypoints', which reads the +control points as waypoints, or 'route', which creates an extra route +named 'control points' containing just the control points in order. +Note that if your goal is to create an arc or other CSV file, you +should use 'none' (or not use this option, which is the same +thing.)

times option

+ Synthesize track times. +

This option causes GPSBabel to read the route as if +it were a track, synthesizing times starting from the current time, using +the estimated travel times specified in your route file (you can change your +travel speeds in the DeLorme product you used to create the route file.)

DeLorme XMap HH Native .WPT (xmap)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Delorme TopoUSA/XMap Conduit is one of the billion CSV +variants mentioned above. It's just like S&A with the addition of +a completely pointless line at the beginning and end of the file. This +is the format used to hot-sync to XMap from withing TopoUSA. Done with +help of Dan Edwards.

DeLorme XMap/SAHH 2006 Native .TXT (xmap2006)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Delorme XMap2006 Conduit is just like XMap, except there are + no spaces between fields and the coordinate format is slightly + different. The completely pointless header and footer lines + are the same, at least. Use this to create the XMapHHWptsSend.txt + file needed to sync to Street Atlas Handheld 2006.

Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file.

DeLorme XMat HH Street Atlas USA .WPT (PPC) (xmapwpt)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+Delorme XMapHandHeld Street Atlas USA is another of the +billion CSV variants. This is the format used by XmapHH SA USA on (at +least) PocketPC O/S. +

+This XMap is not the same as the simpler +XMap format, which is used with Topo USA 4.0 +and XMapHH for Palm. +

+Delorme XMap Handheld .WPT for PocketPC is a bit of a kludge. This +chapter covers XMap Handheld Street Atlas USA edition. +

+XMap on the PocketPC stores its waypoints in individual .wpt files. +For example, waypoints generated by XMap on the PocketPC are stored +by default in the "My Documents" folder using the sequential names +"XMap1.wpt", "XMap2.wpt", ad nauseum. Needless to say, this is not very +efficient. +

+As writing multiple waypoint files is outside of the scope of GPSBabel, +GPSBabel chooses to write one big file, one waypoint per line. +Extracting lines from this file is left as an exercise for the end user. +A simple Perl script to handle this conversion is included at the end +of this chapter. +

+It should also be noted that reading multiple files +is indeed possible, but if you have more than a few points, it can be a task. +For example: +

gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt

+will read the two Xmap .wpt files and write one mapsend file. This +is fine for a small handful of points, but could be quite cumbersome +for folks like me who have 100+ waypoints loaded into XMap. For *nix +folks, something as simple as: +

cat *.wpt > /tmp/foo.wpt
+gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt 

+will do the trick just fine. +

+#!/full/path/to/perl
+$INPUTFILE = @ARGV[0];
+$TARGETDIR = @ARGV[1];
+$FILENAME  = @ARGV[2];
+
+if (! $FILENAME) {
+    print "Usage: xmap_split.pl INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n";
+    print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n";
+    print " (created GPSB0001-GPSBXXXX in /tmp/points/ from points.wpt)\n";
+    exit;
+}
+
+open (INFILE, $INPUTFILE) || die "Cannot open $INPUTFILE for read!\n";
+
+while (<INFILE>) {
+    $lc++;
+    $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc);
+
+    open (OUTFILE, ">$filename") || die "Cannot open $filename for write!\n";
+
+    print OUTFILE $_;
+
+    close(OUTFILE);
+}
+
+exit;
+
+

Contributed to GPSBabel by Alex Mottram.

EasyGPS binary format (easygps)

+ This format can... +

  • + read and write waypoints +

+

This is the binary file format used by EasyGPS. This +format is seemingly being phased out in favor of GPX in newer versions +of EasyGPS, but this allows conversions to and from the old binary +.loc format. +

+ http://www.easygps.com/ +

Information about and sketchy code to implement this file +format were provided by Eric Cloninger. +

FAI/IGC Flight Recorder Data Format (igc)

+ This format can... +

  • + read and write tracks +

  • + read and write routes +

+

+FAI/IGC Data File -- Used by the international gliding +community to record gliding flights. IGC files can be converted to +and from tracks representing recorded flights, and routes representing +task declarations in other formats. +

IGC Data Format Notes

+Refer to Appendix 1 of +http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp +for the specification of the IGC data format. +

+A sample list of software applications that use data in IGC format can be +found at +http://www.fai.org:81/gliding/gnss/gnss_analysis_software.pdf +

+GPSBabel can be used to translate data in IGC format to and from various other +formats. +

+Routes in other formats are used to represent IGC task declarations. +

+Tracks in other formats are used to represent IGC recorded flights. +

Converting to IGC format

+IGC files generated by GPSBabel will NOT pass security validation tests since +the data they contain cannot be proven to originate from an approved flight +recorder. For most software applications that use IGC files this is not an +issue but for competition scoring, record and badge claims the generated files +will not be accepted as proof of a flight. +

+A track stored in another format (GPX for example) representing a recorded +flight can be converted into an IGC file: +

gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc

+If multiple track segments are provided in the input file, the one with the +most points will be used. +

+A route stored in another format representing a task declaration can be +converted into an IGC file: +

gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc

+A route and a track in other formats can be included into a single IGC file: +

gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc

+A similar result can be obtained by downloading the track log and routes +directly from a GPS device connected to a PC. For example to create an IGC +file from data recorded in a Garmin GPS connected to the first serial port of +a PC running Linux: +

gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

+For Windows operating systems: +

gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc

+A waypoint file in another format containing a waypoint whose short name is +"PILOT" can be merged into an IGC file. The description field of the waypoint +will be used for the pilot name in the IGC file header: +

gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc
+gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc

+Some formats such as GPX allow routes, tracks and waypoints to exist in the +same file and can be used to fully populate an IGC file: +

gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc

Converting from IGC format

+Data in an IGC file can be converted into other formats. For example to +generate OziExplorer files containing tracks representing the recorded +flight (myozi.plt) and routes representing declared tasks (myozi.rte): +

gpsbabel -i igc -f myflight.igc -o ozi -F myozi

+Or to GPX format: +

gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx

+Header information from the IGC file will be written to the description field +of the track(s). +

+If both pressure altitude and GNSS altitude are recorded in the IGC file, two +tracks will be written to the new track file, representing the two altitude +tracks. The latitude, longitude and timestamps in the tracks will be identical. +

Merging into IGC format

+A route stored in another format can be merged with an existing IGC file that +has no task declaration, to generate a new IGC file with a task declaration: +

gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc

+A two dimensional (lat/lon) track recorded during a flight by a GPS receiver +can be merged with a one dimensional (altitude) track recorded during the same +flight by a barograph instrument. The result is a three dimensional IGC file +representing the flight: +

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc

+The same can be acheived by downloading directly from a barograph instrument +supported by GPSBabel. For example with a Brauniger IQ Comp GPS variometer: +

gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

+or: +

gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

+(Documentation contributed by Chris Jones, Aug 2004) +

timeadj option

+ (integer sec or 'auto') Barograph to GPS time diff. +

+Sometimes there is a discrepancy between the internal clock in the barograph +instrument and GPS time which can result in the altitude and ground positions +not correlating correctly. This can be corrected manually by passing the time +difference in seconds between the two time domains through the "timeadj" +parameter. This can be any positive or negative integer: +

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc

+GPSBabel can also attempt to deduce the time difference automatically. This +is done by comparing the time that it thinks that you landed on the GPS track +and the barograph and adjusting accordingly: +

gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc

Franson GPSGate Simulation (gpssim)

+ This format can... +

  • + write waypoints +

  • + write tracks +

  • + write routes +

+

+ This is a write-only format used to feed waypoints, tracks, and routes + into Franson Technolgies' + GpsGate simulator. +

+ To use these files in GpsGate, select 'Simulator' and then + "File->Open". +

wayptspd option

+ Default speed for waypoints (knots/hr). +

+ This option specifies the speed of the simulation in knots. +

split option

+ Split input into separate files. +

When this option is specified, GPSBabel will split + split the output into multiple files using the output filename + as a base. For example, if you specify an output file of 'mytrip', +

mytrip-waypoints.gpssim - will contain the waypoints.
mytrip-track0000.gpssim - will contain the first track.
mytrip-track0001.gpssim - will contain the second track.
... and so on.
mytrip-route0000.gpssim - will contain the first route.
mytrip-route0001.gpssim - will contain the seconds route.
... and so on.

+

+Valid values for this option are 0 (off) and 1 (on). The default is '0'. +

Fugawi (fugawi)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This was a requested CSV format, *not* the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel +cannot read tracks in this format, but converting a track into it and +then importing as track in Fugawi works.

It is known to work with Fugawi V3.1.4.635. When +importing/exporting waypoints, one has to specify the order of fields +as follows (names of fields may depend on the language used by +Fugawi):

- Name
- Comment
- Description
- Latidude
- Longitude
- Altitude (metres)
- Date (yyyymmdd/yymmdd)
- Time of day (hhmmss)

When importing tracks, use "[ignore]" instead of "Name", +"Comment" and "Description".

+ http://www.fugawi.com/ +

Garmin 301 Custom position and heartrate (garmin301)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This is a very simple format that +is most useful for exporting data from a Garmin301 to other programs +for analysis. It's a simple comma delimited format that includes the +timestamp, 3D position information and heart rate so you can pull it +into a spreadsheet or graphing program.

Garmin Logbook XML (glogbook)

+ This format can... +

  • + read and write tracks +

+

This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. http://www.garmin.com +

Garmin MapSource - gdb (gdb)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+Support for the "Garmin GPS Database" format used by +default in MapSource versions since release 6.0. By default GPSBabel creates +gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5. +

+Garmin GPS database is an undocumented file format. The +basic info for this module came from the existing MapSource +conversion code. +

cat option

+ Default category on output (1..16). +

+This option specifies the default category for gdb output. It should be a +number from 1 to 16. +

ver option

+ Version of gdb file to generate (1,2). +

+This option specifies the data format version for the output file. Version +2 is the default. Currently, the only other valid value for this option is +1. +

via option

+ Drop route points that do not have an equivalent waypoint (hidden points). +

+This option instructs GPSBabel to drop hidden (calculated) points from +routes. +

Garmin MapSource - mps (mapsource)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+This format supports the Garmin Mapsource™ +product family. +

+This format is based on significant reverse-engineering and guesswork. +GPSBabel's output appears to be compatible with the various versions of +MapSource. Icon mapping is attempted between different MapSource versions. +Altitude is supported, but proximity and depth are not. +

+Naming files *.mps will allow file->open in Mapsource to find the files +more easily. +

+Versions 3, 4, and 5 of the Mapsource data format are handled automatically +on input. By default the output is version 5. (Until 3/2004, it was +version 3, but since Mapsource updates are free, the convenience of +having modern icon sets outweighs the backward compatibility concern. +Users of other versions can either upgrade or specify the switches to +get output in a compatible format.) Waypoints, routes, and tracklogs are +all handled, but map sets are ignored. +

+Information on the Garmin Mapsource format was provided by Ian Cowley and +Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. +

snlen option

+ Length of generated shortnames. +

+This option specifies the length of generated short names on output. The +default is 10 characters. +

snwhite option

+ Allow whitespace synth. shortnames. +

+This option specifies whether to allow whitespace (space, tab, etc.) in +generated short names on output. The default is to not allow whitespace. +

mpsverout option

+ Version of mapsource file to generate (3,4,5). +

+This option specifies the format version for the output file. The default +is version 5, as noted above. Supported versions are 3, 4, and 5. +

mpsmergeout option

+ Merge output with existing file. +

+This option causes the output to be merged with a pre-existing output file. +This allows MapSource sections that aren't handled by GPSBabel (e.g. map sets) +to be preserved. +

mpsusedepth option

+ Use depth values on output (default is ignore). +

+This option causes GPSBabel to write depth values for waypoints. Most +input formats do not support depth values, so the default is to not write +them. +

mpsuseprox option

+ Use proximity values on output (default is ignore). +

+This option causes GPSBabel to write proximity values for waypoints. Most +input formats do not support proximity values, so the default is to not write +them. +

Garmin MapSource - txt (tab delimited) (garmin_txt)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+This is a textual format that contains nearly all of the information +contained in the MapSource main format, GDB. +This format also contains some computed values such as distances between +routepoints and trackpoints, speed, and course (heading). +

+The main goal of garmin_txt is to make aviation data more available. Because +MapSource supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource. +

+During the export with MapSource, some fields are written using local settings +of MapSource and Windows. These include grid format, gps datum, distance and +temperature units, and the representation of date and time fields. GPSBabel +tries to read all items automatically. Problems with date and time format can +be solved with the 'date' and 'time' options. +

Example 3.1. Command showing garmin_txt output with all options

gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" -f in.txt -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 -F out.txt

date option

+ Read/Write date format (i.e. yyyy/mm/dd). +

+This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYYY/MM/DD". +

datum option

+ GPS datum (def. WGS 84). +

+This option specifies the datum to be used on output. Valid values for this +option are listed in Appendix A, Supported Datums. +

dist option

+ Distance unit [m=metric, s=statute]. +

+This option specifies the unit to be used when outputting distance +values. Valid values are M for metric (m/km/kph) or S for statute +(ft/mi/mph). +

prec option

+ Precision of coordinates. +

+This option specifies the precision to be used when writing coordinate values. +Precision is the number of digits after the decimal point. The default +precision is 3. +

temp option

+ Temperature unit [c=Celsius, f=Fahrenheit]. +

+This option specifies the unit to be used when writing temperature values. +Valid values are C for Celsius or F for Fahrenheit. +

time option

+ Read/Write time format (i.e. HH:mm:ss xx). +

+This option specifies the input and output format for the time. The format +is written similarly to those in Windows. An example format is "hh:mm:ss xx". +

utc option

+ Write timestamps with offset x to UTC time. +

+This option specifies the local time zone to use when writing times. It +is specified as an offset from Universal Coordinated Time (UTC) in hours. +Valid values are from -23 to +23. +

Garmin PCX5 (pcx)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

Garmin documents only PCX5, an older format limited to +the lame NMEA six-character waypoint names that's treated as a +second-class citizien in current versions of MapSource. In Mapsource, +use file->import to read these files. If you name the files *.wpt, +Mapsource will find them easier. +

In general, you should prefer the "mapsource" file format +to this one. +

deficon option

+ Default icon name. +

cartoexploreur option

+ Write tracks compatible with Carto Exploreur. +

Garmin POI database (garmin_poi)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

The Garmin POI loader +loads custom points of interest into certain models of +Garmin GPS receivers. (As of this writing, only the models introduced +in 2005 and later are supported. See Garmin's site for more info.) +This is the format readable that that program.

Garmin serial/USB protocol (garmin)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+ GPSBabel supports a wide variety of Garmin hardware via serial + on most operating systems and USB on Windows, Linux, and OS X. +

+ For serial models, be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. +

+ Supported models on USB include +

Edge 205Foretrex 201GPSMAP 60CSNuvi 350[1]StreetPilot 7500
Edge 305Foretrex 301GPSMAP 60CSXNuvi 360[1]StreetPilot c310
eTrex Legend CGPSMAP 195GPSMAP 60CXQuestStreetPilot c320
eTrex LegendCXGPSMAP 276CGPSMAP 76CQuest IIStreetPilot c330
eTrex Venture CGPSMAP 295GPSMAP 76CSStreetPilot 2610StreetPilot c340
eTrex Venture CXGPSMAP 296CGPSMAP 76CSXStreetPilot 2620StreetPilot c510[1]
eTrex VistaCGPSMAP 378GPSMAP 76CXStreetPilot 2650StreetPilot c530[1]
eTrex Vista CXGPSMAP 396GPSMAP 96StreetPilot 2720StreetPilot c550[1]
Forerunner 205GPSMAP 478GPSMAP 96CStreetPilot 2730StreetPilot i2
Forerunner 301GPSMAP 496Nuvi 300[1]StreetPilot 2820StreetPilot i3
Forerunner 305GPSMAP 60CNuvi 310[1]StreetPilot 7200StreetPilot i5

+

and most serial units including: +

eMapeTrex VistaGeko 301GPS III StreetPilot III
eTrex CamoeTrex YellowGPS 12CX GPS III+ StreetPilot III+
eTrex LegendForerunner 201GPS 12Map GPS II  
eTrex SummitForetrex 201GPS 12 GPS II+  
eTrex VentureGeko 201GPS 12XL GPS V 

+

+ None of the GPSBabel developers has access to every model on that + list, but we've received reports of success and/or have reasonable + expectations that the above models work. If you succeed with + a model that is not on that list, please send a message to the + gpsbabel-misc mailing list with the details so that we may add it. +

+ Not every feature on every model is supported. For example, + while we do extract data such as heart rate and temperature from + tracks on the sporting models like Edge and Forerunner, GPSBabel + is not a fitness program at its core and does not support features + like courses or calorie/fitness zone data. +

+ To communicate with a unit serially, use the name of that + serial port such as "COM1" or "/dev/cu.serial". +

+ To communicate via USB use "usb:" as the filename on all OSes. + Thus, to read the waypoints from a Garmin USB unit and write + them to a GPX file: + +

gpsbabel -i garmin -f usb: -o gpx -F blah.gpx

+ +

+ If you have multiple units attached via USB, you may provide + a unit number, with zero being the implied default. So if you + have three USB models on your system, they can be addressed as + "usb:0", "usb:1", and "usb:2". To get a list of recognized devices, + specifiy a negative number such as: +

gpsbabel -i garmin -f usb:-1

+When reporting problems with the Garmin format, be sure to include +the full unit model, firmware version, and be prepared to offer +debugging dumps by adding "-D9" to the command line, like: +

 gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx

+Custom icons are supported on units that support that. +Neither GPSBabel nor your firmware know what is associated with any +given slot number. They don't know that the picture you placed in the +first slot is a happy face, they only know they're in the lowest +numbered slot. GPSBabel names the them consistently with Mapsource, +so they are named 'Custom 0' through 'Custom 511'. +

+ For models where the connection on the GPS is a serial interface, + be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. +

+ For models connected via USB, we recommend use of the 'usb:' + filename. For this to work on Windows, you must install + the Garmin driver. For Linux, this will fail if have the garmin_gps + kernel module loaded. + See the Operating System Notes for details. +

snlen option

+ Length of generated shortnames. +

This option overrides the internal logic to figure out how many +characters an addressed Garmin GPS will support when using the '-s' smartname +option. This should be necessary only if you have a receiver type that +GPSBabel doesn't know about or if you want to "dumb down" one unit to match +another, such as wanting waypoint names in a StreetPilot 2720 (which supports +20 character names) to exactly match those in a 60CS (which supports 10). +

snwhite option

+ Allow whitespace synth. shortnames. +

This options controls whether spaces are allowed in generated +smart names when using the '-s' option.

deficon option

+ Default icon name. +

+This option specifies the icon or waypoint type to write for each waypoint on +output. +

+If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. +

+Value specified may be a number from the Garmin Protocol Spec or a name +as described in the Appendix B, Garmin Icons. +

+This option has no effect on input. +

get_posn option

+ Return current position as a waypoint. +

This options gets the current longtitude and latitude from the attached GPS device +and returns it as a single waypoint for further processing. For example, +to return the current position from a USB Garmin to a KML file: +

gpsbabel -i garmin,get_posn -f usb: -o kml -F myposition.kml

+

power_off option

+ Command unit to power itself down. +

This command forces an immediate powerdown of the addressed Garmin +receiver. It is ignored on hardware that does not support this command. +Obviously, further processing once you have sent a "power off" command to +a unit that supports it is rather futile, so place this option carefully +in your command. + +

gpsbabel -o garmin,power_off -F /dev/ttyS0

+

category option

+ Category number to use for written waypoints. +

This numeric option will force waypoints to be written with that +category number when sending to a Garmin receiver that has category +support. It is ignored on receivers without that capability.

Garmin Training Centerxml (gtrnctr)

+ This format can... +

  • + write tracks +

+

+Garmin Training Center is the successor to Garmin' Logbook program +for their workout units. It is a free upgrade. +

+This format is somewhat underachieving in GPSBabel. It is a write-only +format; we never read it. The bigger problem, however, is a fundamental +impedance mismatch between this format and most of what we support. GPSBabel +fundamentally deals in waypoints, tracks, and routes. While we do record +things like heart rate and temperature when we know it, the fundamentals +of Training Center are different - it deals in concepts like laps and calories +which are rather alien to GPSBabel and most of the formats we support. As +such, while we can describe the tracks pretty accurately, things like +calories and heart zone tracking are not supported. +

Geocaching.com .loc (geo)

+ This format can... +

  • + read and write waypoints +

+

+This format supports the Geocaching.com/EasyGPS ".loc" format. This format +was created specifically for Geocaching.com and is not the same as the +standard EasyGPS .loc format. See the EasyGPS +or GPX formats for more general EasyGPS support. +

+This is a simple XML-based format containing only very basic information +about geocaches. If you can use the GPX +format instead, you should consider doing so as it is a much richer format. +

deficon option

+ Default icon name. +

+This option specifies the icon or waypoint type to write for each waypoint on +output. +

+If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. +

+There is no list of valid values for this option. +

+This option has no effect on input. +

nuke_placer option

+ Omit Placer name. +

+If this option is specified, GPSBabel will not read geocache placer information +from a .loc file on input. That is, it will ignore any placeer names in the +input file. +

+This option has no effect on output. +

GeocachingDB for Palm/OS (gcdb)

+ This format can... +

  • + read and write waypoints +

+

This is the GeocachingDB by DougsBrat. It works with v2 +and v3 of this program. See vip.hyperusa.com +

GEOnet Names Server (GNS) (geonet)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Input support for the GEOnet Names Server (GNS) country +file structure. Export to this format is not possible, as this format +has too many fields that we never get populated by any other +format.

GeoNiche .pdb (geoniche)

+ This format can... +

  • + read and write waypoints +

+

Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. See +nwlink.com +

dbname option

+ Database name (filename). +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

category option

+ Category name (Cache). +

+This option specifies the name of the category in which to place the +waypoints. If this option is not specified, the default category is +"Cache". +

Google Earth (Keyhole) Markup Language (kml)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+KML, the Keyhole Markup Language, is used by Keyhole and +Google Earth. There are features in this file format that GPSBabel +doesn't support - such as camera views - but waypoints, tracks, and routes +work well. +

+Google Earth also uses GPSBabel internally for receiver communications +and several file format imports and exports. +

deficon option

+ Default icon name. +

+This option specifies the default name for waypoint icons +

lines option

+ Export linestrings for tracks and routes. +

+When this option is nonzero, GPSBabel draws lines between points in +tracks and routes. The default value for this option is 1, which causes +lines to be drawn by default. To disable line-drawing, specify +lines=0. +

points option

+ Export placemarks for tracks and routes. +

+When this option is nonzero, GPSBabel draws placemarks for tracks and routes. +The default value for this option is 1, which causes placemarks to be drawn. +To disable drawing of placemarks, specify points=0. +

line_width option

+ Width of lines, in pixels. +

+This option specifies the width of the drawn lines in pixels. The default +value is six pixels. +

line_color option

+ Line color, specified in hex AABBGGRR. +

+This option specifies the line color as a hexadecimal number in +AABBGGRR format, where A is alpha, B is blue, G is green, and R is red. +

floating option

+ Altitudes are absolute and not clamped to ground. +

+When this option is nonzero, altitudes are allowed to float above or below +the ground surface. By default, this option is zero so that altitudes are +clamped to the ground. Specify floating=1 to allow them to +float. +

+This option is more useful to pilots than to hikers. +

extrude option

+ Draw extrusion line from trackpoint to ground. +

+This option is a boolean flag to specicy whether Google Earth should +draw lines from trackpoints to the ground. It defaults to '0', which +means no extrusion lines are drawn. The option of '1' is, of course, +most useful for points that aren't actually on the ground such as those +be captured from planes. +

trackdata option

+ Include extended data for trackpoints (default = 1). +

+This is a boolean flag that controls +whether GPSBabel writes extensive data for each trackpoint generated. +By default computed speed, timestamps, and so on are written with the default +of '1' for this option. If you are writing large tracks and do not value +this information, you can reduce the size of the generated file substantially +by turning this flag off by setting it to '0'. +

units option

+ Units used when writing comments ('s'tatute or 'm'etric). +

+Units is a simple option. Specify 's' for "statute" (miles, feet, and +other things that don't sensibly convert to each other, but are craved +by Americans) or 'm' for "metric". +

labels option

+ Display labels on track and routepoints (default = 1). +

+When this option is zero, no labels are added for track and route points. +This option defaults to one, so labels are added by default. +

max_position_points option

+ Retain at most this number of position points (0 = unlimited). +

+ This option allows you to specify the number of points kept + in the 'snail trail' generated in the realtime tracking mode. +

Google Maps XML (google)

+ This format can... +

  • + read tracks +

+

This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Maps route URL (use +the "link to this page" option to get a usable URL.) This allows you +to plan a route using Google Maps, then download it and use it in your +own mapping program or GPS receiver. To get a file suitable for use +with GPSBabel, plan your route as usual with Google Maps. Once you've +got it the way you want it, click the "Link to this page" link in the +upper right-hand corner of the Google Maps page. Then, edit the URL +that appears in your address bar by adding "&output=js" (without +the quotes) onto the end. Hit enter, and the resulting page will be +mostly empty. It doesn't look like much, but it contains exactly what +GPSBabel needs. Save it to disk using whatever menu option your web +browser provides. +

+Note that if you are using Microsoft Internet Explorer, you should make sure +to save the web page as "Web Page, HTML Only". If you save it as "Web Page, +Complete", it will be reformatted into a non-XHTML format that GPSBabel +cannot read. +

+If you use a Unix-compatible +operating system, this shell script might be useful: +

+#!/bin/sh 
+FROM="233 S. Upper Wacker Dr, Chicago, IL" 
+TO="1060 W. Addison St, Chicago, IL" 
+wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \
+2&>/dev/null >google_map.js
+gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx
+

GpilotS (gpilots)

+ This format can... +

  • + read and write waypoints +

+

This is a Palm/OS file format for GPilotS. It was tested +against version 6.2. +

+ http://www.cru.fr/perso/cc/GPilotS/ +

Neither tracks nor routes are supported at this +time.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

GPS TrackMaker (gtm)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

Input and output support for waypoints, tracks and routes in + the GPS TrackMaker + binary format.

Code implemented by Gustavo Niemeyer.

GPSBabel arc filter file (arc)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+This format is used by GPSBabel itself as the input to the +arc and +polygon filters. See those filters +for more information. +

GpsDrive Format (gpsdrive)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

GpsDrive way.txt file format. A space seperated format +file. Tested against GpsDrive v 1.30 found at kraftvoll.at. +Contributed by Alan Curry.

GpsDrive Format for Tracks (gpsdrivetrack)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Format used by GpsDrive to save tracks. Like GPSDRIVE a +space seperated format file. See above for a link to GpsDrive. +Contributed by Tobias Minich.

GPSman (gpsman)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

GPS Manager +can read and write formats GPSBabel doesn't understand. The format defaults +(WGS84, DDD) work reliably. Tracks, routes, and non-default format options +are not supported. +

This format is documented at the GPS Manager + doc site. +

GPSPilot Tracker for Palm/OS (gpspilot)

+ This format can... +

  • + read and write waypoints +

+

The file format for GPSPILOT gpspilot.com was provided by Ron +Parker. The output from this module has been tested with GPSPilot +Tracker v5.05sx, but it is based on reverse-engineering so it may not +work with all versions of all GPSPilot products. It had read-only +support for Airport, Navaid, City and Landmark files but will read and +write Point files.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

gpsutil (gpsutil)

+ This format can... +

  • + read and write waypoints +

+

GPSUtil has a simple file format of this program that runs +on POSIX- compliant OSes like UNIX and Linux. Reads and writes of +this format are reliable. (I've also contributed to this program.) +It's available at cs.uakron.edu.

GPX XML (gpx)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

This is the most capable and expressive of all the file +formats supplied. It is described at topografix.com and is +supported by EasyGPS, ExpertGPS, and many other programs described at +topografix.com +

snlen option

+ Length of generated shortnames. +

suppresswhite option

+ No whitespace in generated shortnames. +

logpoint option

+ Create waypoints from geocache log entries. +

urlbase option

+ Base URL for link tag in output. +

gpxver option

+ Target GPX version for output. +

+This option specifies the version of the GPX specification to use for +output. The default version is 1.0. The only other valid value for this +option is 1.1. +

+Notice that this is not a full scale XML schema conversion. In particular, +if you have a GPX 1.0 file that has extended namespaces in it (such as a +pocket query from Geocaching.com) just writing it with this option will +result in a horribly mangled GPX file as we can't convert the schema data. +

HikeTech (hiketech)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

+

This is the .gps format used by the Mac OS X applications +written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. +More information about these products can be found at hiketech.com +

Holux (gm-100) .wpo Format (holux)

+ This format can... +

  • + read and write waypoints +

+

The Holuxgm-100 (e-fox) gps receiver uses standard +compact flash cards. File formats were provided by Holux-Taiwan +holux.com to the author. +The code was tested against version 2.27E1; other versions and +receivers may work but have not been explictly tested. Anyone with +information on other Holux receivers is encouraged to contact +jochen@bauerbahn.net. +

When copying the .wpo file to a flash card, the file must +be named tempwprt.wpo as the +receiver will ignore all other files. +

Comparing the waypoints of a .wpo files against other +formats like .gpx you may notice a small difference in the latitude +and longitude values. The reason is the low resolution of the +coordinates in the wpo file format. In a .wpo file the reolution is +1/10"; in gpx for example it is 1/100". A a practical matter, this +loss is only about 1.7 meters (5 feet). +

The generated waypoint failes can also be used by MapShow +version 1.14. This program is free of charge from the Holux web site. +

This format was contributed by Jochen Becker. +

HSA Endeavour Navigator export File (hsandv)

+ This format can... +

  • + read and write waypoints +

+

HSA Systems Endeavour Navigator format - will import both +the old version 4.x binary files, and the newer XML based ones. Only +writes the new XML (5.0 and above) format. (use the .exp +extension)

HTML Output (html)

+ This format can... +

  • + write waypoints +

+

HTML output generates a single HTML file of all of the +waypoints in the input file. It supports a number of Groundspeak GPX +extensions, as well as filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. +

The following command line reads a GPX file with +Groundspeak extensions and writes an HTML file with encrypted hints +that is rendered using a custom stylesheet: +

gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html

stylesheet option

+ Path to HTML style sheet. +

+Use this option to specify a CSS style sheet to be used with the +resulting HTML file. +

encrypt option

+ Encrypt hints using ROT13. +

+Use this option to encrypt hints from Groundspeak GPX files. +

logs option

+ Include groundspeak logs if present. +

+Use this option to include Groundspeak cache logs in the created document. +

degformat option

+ Degrees output as 'ddd', 'dmm'(default) or 'dms'. +

+When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. +

altunits option

+ Units for altitude (f)eet or (m)etres. +

+This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. +

IGN Rando track files (ignrando)

+ This format can... +

  • + read and write tracks +

+

+This format supports IGN Rando track files. IGN Rando is a program mainly +used in France for Topo maps. The files are XML based and are "windows-1252" +encoded. Trackpoints do not have time stamps. +

index option

+ Index of track to write (if more the one in source). +

+Because the format supports only one track, this option may be used +on output to select a single track from a collection of +tracks read from a more expressive format. If you have, say, a +gpx file that contains two tracks, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f tracks.gpx -o ignrando,index=1 -F track1.txt -o ignrando,index=2 -F track2.txt

Kartex 5 Track File (ktf2)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Support for Kartex 5 trackfiles. For more info see kwf2.

Kartex 5 Waypoint File (kwf2)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Support for Kartex 5 waypoint files. Kartex is a Swedish + map and GPS positioning system. GPSBabel can read and write + files from Kartex 4 and 5 with WGS84 coordinates. UTM or + Swedish grid are not supported. +

KuDaTa PsiTrex text (psitrex)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

This is a text format created by KuDaTa's PsiTrex program +for the Psion PDAs. The format can't be readily handled by XCSV, so +this format is handled explicitly. Waypoints, routes and tracks are +all handled, with icon names used corresponding to verison 1.13 of +PsiTrex. This module was contributed to GPSBabel by Mark +Bradley.

Lowrance USR (lowranceusr)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+The Lowrance iFinder GPS series has the unique capability +to output its data to an MMC card. The data is saved to the card as a +.USR file and can be read by your computer using a card reader. +Waypoints, routes, tracks are supported. By default, Event marker +icons are converted to waypoints. Symbols tend to get lost in the +translation. +

ignoreicons option

+ Ignore event marker icons. +

+This option instructs GPSBabel to not convert icons to waypoints on input. +

merge option

+ (USR output) Merge into one segmented track. +

+This option merges all tracks into a single track with multiple segments. +

break option

+ (USR input) Break segments into separate tracks. +

+This option breaks track segments into separate tracks when reading a .USR +file. +

Magellan Explorist Geocaching (maggeo)

+ This format can... +

  • + write waypoints +

+

The SD card format used by the Magellan Explorist 400, +500, and 600 to describe geocaches. Notice what while the format can +hold an infinite number of geocaches, the unit will read and silently +discard all but 200 geocache POIs at a time.

You should name any file created with this format with a +".gs" extension so the firmware can read it. +

Magellan Mapsend (mapsend)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+This format supports the Magellan MapSend™ native +file format. +

+Kudos to Magellan for having the foresight to document their file formats, +making software like this possible. +

trkver option

+ MapSend version TRK file to generate (3,4). +

+This option sets the MapSend version to generate TRK files, +since new MapSend versions can't open version 3 files. +Valid values are 3 (MapSend v3.0) or 4 (MapSend v4.0 and v4.1). +

Magellan NAV Companion for Palm/OS (magnav)

+ This format can... +

  • + read and write waypoints +

+

+Magellan NAV Companion for Palm/OS is not really designed +for this sort of use, but its file format is supported and with a +little bit of patience you can both read and write NAV Companion +waypoints. This conversion is based on +partially incomplete reverse-engineering of the record format, so it +may not work with all versions of NAV Companion. It has been tested +with version 2.10 and 3.20. +

+Translating NAV Companion waypoints to another format is as easy +as with any other format. Just find the Companion_Waypoints database +in your palm backup directory and use it as the input file. +

+When translating waypoints back to NAV Companion, though, you need +to jump through some hoops: +

+First, you must merge any waypoints that already exist in the database +in your Palm Backup directory with the ones you are adding; failure to +do so will result in only the new points being available in NAV Companion, +even if you give the new database a different name (it will overwrite +the old database, even in your backup directory. That's a feature of +PalmOS, not of NAV Companion.) +

+To merge the databases, use a command line like the following: +

gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb

+Second, you must use the installer to install your new PDB file. Don't +make the mistake of copying it over the existing Companion_Waypoints.PDB +file; the one on the handheld will overwrite it rather than merging with +it. +

+Finally, because NAV Companion is not designed to work with desktop +applications, you must tell NAV Companion that its waypoints database +has changed out from under it. One way to do this is to go to the +waypoints screen and attempt to scroll; that will force it to reread +the database and fix the record pointers that it keeps on the heap. +

Magellan SD files (as for eXplorist) (magellanx)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+ This is the SD card format used by the Magellan Explorist 400, + 500, 600, and XL and internally on those devices plus the + Explorist 210. Waypoints are identical to the Magellan SD format + used by Meridian, but allows longer waypoint names. Routes are + subtly different. +

+ You should name any file containing waypoints created with + this format with a ".upt" extension so the firmware can read it. + Similarly, routes should be named ".rte" and tracks should be + named ".log". +

deficon option

+ Default icon name. +

maxcmts option

+ Max number of comments to write (maxcmts=200). +

+The maxcmts option allows you to specify the number comments that will +be sent to the unit. +

+Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. +

Magellan SD files (as for Meridian) (magellan)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

GPSBabel supports the following Magellan receivers: +

310Meridian Color
315Explorist 100 (with aftermarket cable)
Map330Explorist 200 (with aftermarket cable)
SporTrak Map ColorExplorist 300 (with aftermarket cable)
SporTrak MapExplorist 210
SporTrak Map ProExplorist 300
SporTrak Map TopoExplorist 400
Meridian (green or yellow)Explorist 500
Meridian GoldExplorist 600
Meridian PlatinumExplorist XL

+

+ This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, 400, 500, 600, XL) or on removable memory. +

+ If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. +

deficon option

+ Default icon name. +

maxcmts option

+ Max number of comments to write (maxcmts=200). +

+The maxcmts option allows you to specify the number comments that will +be sent to the unit. +

+Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. +

Magellan serial protocol (magellan)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

GPSBabel supports the following Magellan receivers: +

310Meridian Color
315Explorist 100 (with aftermarket cable)
Map330Explorist 200 (with aftermarket cable)
SporTrak Map ColorExplorist 300 (with aftermarket cable)
SporTrak MapExplorist 210
SporTrak Map ProExplorist 300
SporTrak Map TopoExplorist 400
Meridian (green or yellow)Explorist 500
Meridian GoldExplorist 600
Meridian PlatinumExplorist XL

+

+The RoadMate family of products is not supported. +

+ This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, 400, 500, 600, XL) or on removable memory. +

+ If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. +

deficon option

+ Default icon name. +

+This option specifies the icon or waypoint type to write for each waypoint on +output. +

+If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. +

+This option has no effect on input. +

maxcmts option

+ Max number of comments to write (maxcmts=200). +

+The maxcmts option allows you to specify the number comments that will +be sent to the unit. +

+Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. +

baud option

+ Numeric value of bitrate (baud=4800). +

+ This option causes GPSBabel to use the given baud rate for serial + communications. It must match the given baud rate on the receiver. The + default value matches the default on the receiver, 4800. +

+ Valid options are 1200, 2400, 4800, 9600, 19200, 57600, and 115200. +

noack option

+ Suppress use of handshaking in name of speed. +

+Magellan's protocol specification strongly encourages the use of software +acknowledgements on every packets. This is a simple "this is what I think +I heard. If you agree that I heard it correctly, let's go to the next packet" +handshake that is used to ensure the integrity of the data transfer. +

+Certain firmware versions have problems handling this which makes transfers +unnecessarily slow. Transfers on all units at high serial speeds are also +severely restricted by this process. +

+In controlled environments (good cables, low electrical noise, receiving +from the unit, not doing donuts with the unit set to "track up" at a 150 +mile scale with 500 waypoints on the screen) it is sometimes useful to +release that safety belt by using the "noack" suboption. +

nukewpt option

+ Delete all waypoints. +

+This option erases all waypoints in the receiver before doing a transfer. +

+This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending waypoints to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. +

Map&Guide 'TourExchangeFormat' XML (tef)

+ This format can... +

  • + read routes +

+

+TEF, internally called "TourExchangeFormat", is an XML based export format +used by Map&Guide Motorrad-Routenplaner 2005/06™. +

+Because this is only an export format, GPSBabel does not support writing to +this format. +

+GPSBabel also supports the bcr format, which +may also be used with this program and supports both reading and writing. +

 gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx

routevia option

+ Include only via stations in route. +

+This option may be used to eliminate calculated route points from the route. +

Map&Guide to Palm/OS exported files (.pdb) (mag_pdb)

+ This format can... +

  • + read waypoints +

  • + read routes +

+

With this format we support the Palm/OS export for +Map&Guide based products like "PowerRoute", +"Motorrad-Routenplaner" and (maybe) other software. The exported files +can contain maps and/or route descriptions. The reader for this format +has been tested with PowerRoute 5+6, Motorrad-Routenplaner +2002(-2006).

Mapopolis.com Mapconverter CSV (mapconverter)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+Mapconverter is a format that is read by Mapopolis.com's +mapconverter application. +

+Mapconverter is an application used to create userland maps and map data for +Mapopolis.com's Mapopolis program. The mapconverter format is essentially +waypoint data prepared in a format that the mapconverter application will +accept. +

+The steps for using GPSBabel and Mapconverter go something like this: +

+Step 1: Create a mapconverter file using gpsbabel. +

gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt

+Step 2: Launch mapconverter.exe and choose foo.txt as your input file. + Click the begin button to have mapconverter process foo.txt. +

+If all goes successfully, you should have a file called "foo.pdb" ready +for syncing with your PDA. Put it wherever Mapopolis thinks it should be +on your PDA. +

Notes

  • +GPSBabel will write the name of its own output file in the output file + it creates as the input for Mapconverter. Mapconverter will replace + the extension of this filename with ".pdb". +

  • +The PocketPC version of Mapopolis doesn't notice files with the ".pdb" + extension. To make this work, change the extension to ".mlp" when + copying the mapconverter output to your PocketPC PDA. +

  • +Mapconverter only works with Mapopolis version 3.x. Mapopolis version + 4 will refuse to load mapconverter maps. There is no known work-around + for this at the time of this writing. +

  • +Mapconverter is no longer available from the Mapopolis website. If you + need a copy of mapconverter, ask on your local GPS Software discussion + forum and I'm sure someone will have it. As far as I know, It was never + actually acknowledged/supported by Mapopolis to begin with. +

MapTech Exchange Format (mxf)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Maptech Exchange Format - Another CSV format file. This +format complies with (at least) Maptech Terrain Navigator, Terrain +Professional, Take a Hike, and ExpertGPS import/export MFX. +Contributed by Alex Mottram.

Microsoft AutoRoute 2002 (pin/route reader) (msroute)

+ This format can... +

  • + read routes +

+

Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported.

Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions.

One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. +

Microsoft Streets and Trips (pin/route reader) (msroute)

+ This format can... +

  • + read routes +

+

Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported.

Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions.

One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. +

Microsoft Streets and Trips 2002-2006 (s_and_t)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This is a format for importing into Microsoft Streets and +Trips. It's been exercised on versions 2003, 2004, and 2005. Detailed +instructions on how to use it, including preserving hyperlinks, are at +gpsbabel.org +

Motorrad Routenplaner (Map&Guide) .bcr files (bcr)

+ This format can... +

  • + read and write routes +

+

+This file format (extension .bcr) is used in Map&Guide +Motorrad Routenplaner 2002™ and later versions. +BCR is a route-only format. If you own a newer release (2005 or later) you +may also use the XML export with GPSBabel's tef +input format. +

+There may be other products from Map&Guide that use this format as well. +

+Coordinates are stored in a BCR file in a Mercator projection. The +conversion from the Mercator projection to polar (latitude/longitude) +coordinates and back again may result in visible differences. Experience +reports are welcome. +

Example 3.2. Sample BCR command with all options

gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr

index option

+ Index of route to write (if more the one in source). +

+Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o bcr,index=1 -F route1.bcr -o bcr,index=2 -F route2.bcr

name option

+ New name for the route. +

+This route specifies the name of the route. This is particularly useful if +the route came from an input format that did not support named routes, but +it may also be used to rename a route. +

radius option

+ Radius of our big earth (default 6371000 meters). +

+This option instructs GPSBabel to use a different value for the radius of +the earth when converting between the Mercator projection and geographic +coordinates. The default value is 6371000.0 meters. +

+Careful experimentation with this value may help to reduce conversion +errors. +

MS PocketStreets 2002 Pushpin (psp)

+ This format can... +

  • + read and write waypoints +

+

+Microsoft's PocketStreets 2002 Pushpin (.PSP) format is +not yet completely documented. The .PSP module does not work with +MS Streets & Trips 2002 .EST files To create .PSP files from +Streets & Trips 2002, you will need to have PocketStreets support +installed. +

+Please note that MS Streets & Trips only exports +.PSP files. It does not import them. MS Streets & Trips 2002 only +imports CSV files. To use .PSP files, simply copy them over to the +same folder on the mobile device as the map (.MPS), and open +PocketStreets. It should also be noted that in the case a pushpin is +outside of the exported map area, the pin will be "grayed-out" and +unused in PocketStreets. This is a good thing as it allows us to +create one big .PSP file that covers multiple .MPS files. +Unfortunately, you need one .PSP file for every .MPS file. +

Frequently Asked Questions

1. +Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? +
2. +I keep getting a blank (32 byte) PSP file. +
3. +I've created a PSP file, now what do I do with it? +
4. +I don't have a map. What do I do now? +
5. +I have .EST files, not .PSP files. What's up with that? +
6. + The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to + create them. What's up? +
7. +Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? +
8. + Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? +
9. +Does GPSBabel/psp work with (insert your country/location here) maps? +
10. +What do you mean S&T writes points with the wrong coordinates? +
11. +I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? +
12. +Where can I find documentation for the layout of PSP files? +
13. +I have some other problem, what do I do? +
1.

+Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? +

+GPSBabel/psp has the advantage of being able to create pushpins +without + creating the associated map file and the need to "import" the waypoint + data into S&T. Through a series of scripts, you can create a dozen + or so PSP files in a few seconds as opposed to a few weeks using the + S&T interface. The maps are not going to change between sessions, + only the pins will. Why waste all that time creating maps when all you + really want are updated pins? As an aside, GPSBabel/psp creates points + with the proper coordinates + where S&T does not in some areas of the U.S. + (Nashville, TN for instance). +

2.

+I keep getting a blank (32 byte) PSP file. +

+There are either no points to write, or you have botched the command + line for GPSBabel. GPSBabel is sensitive to UPPER and lower case + on the command line. A simple command line to create PSP files + looks like this: +

gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp

+ Note the use of "-f" for INPUT files and "-F" for OUTPUT files. +

3.

+I've created a PSP file, now what do I do with it? +

+To use pushpins in Pocketstreets, you need to have both a map and a + pushpin file. These two files must exist in the same folder and have + exactly the same base name as the map. For example, the pins that + correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". +

4.

+I don't have a map. What do I do now? +

+Create one using the "Export map to Pocketstreets" option in S&T. You + can also pick up some major city maps on the web from the MS Pocketstreets + website if you are interested in seeing how it works. +

5.

+I have .EST files, not .PSP files. What's up with that? +

+In order to make PSP files, you need to use the "Export map to + Pocketstreets" function in S&T. .EST files are for use in S&T, not + Pocketstreets. +

6.

+ The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to + create them. What's up? +

+Pocketstreets makes corrections to the S&T waypoint data upon initial + loading. GPSBabel/psp writes PSP files with these corrections already made. + Ask MS. +

7.

+Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? +

+As of this writing, I haven't seen any so I can't be sure. If they + follow the same layout as S&T 2002, I'd imagine so. +

8.

+ Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? +

+MS changed the file layout between S&T 2001 and S&T 2002. The GPSBabel psp + module is known to work fine with S&T 2002 and 2003. +

9.

+Does GPSBabel/psp work with (insert your country/location here) maps? +

+If it doesn't, feel free to inquire on the +GPSBabel-Misc +mailing list. +

10.

+What do you mean S&T writes points with the wrong coordinates? +

+At some point in the "Export map to Pocketstreets" function in S&T, + it goofs the lat/long data. Points in Nashville tended to shift + 1.4 miles WEST of their original location. I'm not a geometry buff, + but I'd imagine they have a reference point for generating coordinates + that's wrong in (at least) that area. +

11.

+I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? +

+ No. Pocketstreets will "ignore" points that are outside of the map + area. Points that are not on the current map will be "grayed out" + in pushpin explorer in Pocketsreets. This is the reason the PSP + module was written for GPSBabel in the first place. +

12.

+Where can I find documentation for the layout of PSP files? +

+Just about everything I know about the PSP file format is documented + in the source. To the best of my knowledge, there is no documentation + (and for good reason, I've come to discover). +

13.

+I have some other problem, what do I do? +

+Ask your question on the GPSBabel-Misc mailing list. +

National Geographic Topo .tpg (waypoints) (tpg)

+ This format can... +

  • + read and write waypoints +

+

National Geographic Topo! Waypoint and Route Format. This module +reads and writes .TPG files created by various editions of NG Topo! +Reading/writing of route data is not supported yet.

Contributed by Alex Mottram.

datum option

+ Datum (default=NAD27). +

The option 'datum="datum name"' can be used to override +the default of NAD27 ("N. America 1927 mean") which is correct for the +continental U.S. Points in Hawaii should use "Old +Hawaiian_mean"

National Geographic Topo 2.x .tpo (tpo2)

+ This format can... +

  • + read tracks +

+

+ This module reads tracks from .TPO files created by + National Geographic Topo! version 2.x +

+ Contributed by Steve Chamberlin. +

National Geographic Topo 3.x/4.x .tpo (tpo3)

+ This format can... +

  • + read waypoints +

  • + read tracks +

  • + read routes +

+

This module reads .TPO files created by National Geographic Topo! version +3.x and 4.x. It will read tracks, routes, waypoints, map notes, symbols, and +text notes. The latter three are converted to waypoints.

Contributed by Curt Mills.

Navicache.com XML (navicache)

+ This format can... +

  • + read waypoints +

+

This is the XML format that's used by Navicache.com for +their geocaching data. There are a number of fields in it that are +marked "required" but are Navicache-specific, so GPSBabel can not +write these files, but we can still read them. navicache.com +

noretired option

+ Suppress retired geocaches. +

Navigon Mobile Navigator .rte files (nmn4)

+ This format can... +

  • + read and write routes +

+

Support for Navigon Mobile Navigator route (.rte) files. +This is a very simple text format that only requires coordinates, but +has fields for many other things. We only write coordinates as fields +like 'city' and 'street' cannot typically be populated from other +formats. www.navigon.com +

index option

+ Index of route to write (if more the one in source). +

+Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o nmn4,index=1 -F route1.rte -o nmn4,index=2 -F route2.rte

Navitrak DNA marker format (dna)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Navitrak DNA marker format - Another CSV format file. This +is the format that is compatible with the DNA Desktop import/export +command. Reading the binary Markers.jwp format directly off the data +card is not supported yet. Contributed by Tim Zickus.

NetStumbler Summary File (text) (netstumbler)

+ This format can... +

  • + read waypoints +

+

+This format reads summary files from NetStumbler™ +0.4 or MacStumbler™. +

+The default behavior when creating waypoints is to use the SSID for +the short name, and information about the access point for the +description. When the SSID is not unique, is not available, or +consists of whitespace, a short name is synthesized. +

+Different icons are assigned to encrypted, +non-encrypted, stealth, and non-stealth access points; these may be +changed with options. +

+NetStumbler +

+MacStumbler +

nseicon option

+ Non-stealth encrypted icon name. +

+This option specifies the name of the icon to use for +non-stealth, encrypted access points. +

nsneicon option

+ Non-stealth non-encrypted icon name. +

+This option specifies the name of the icon to use for +non-stealth, non-encrypted access points. +

seicon option

+ Stealth encrypted icon name. +

+This option specifies the name of the icon to use for +stealth, encrypted access points. +

sneicon option

+ Stealth non-encrypted icon name. +

+This option specifies the name of the icon to use for +stealth, non-encrypted access points. +

snmac option

+ Shortname is MAC address. +

+This option causes GPSBabel to use the MAC address as the short name for the +waypoint. The unmodified SSID is included in the waypoint description. +

NIMA/GNIS Geographic Names File (nima)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

This is a CSV format from the National Imagery and Mapping +Agency.

NMEA 0183 sentences (nmea)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

+

This format is the file representation of the NMEA +(National Marine Electronics Association) 0183 +log and waypoint format for GPS devices. Some hardware and software +that work with NMEA-0183 formatted data include: +

+ GPS Data Logger + + NMEAlog + + GeoConv +
+ GPS TrackMaker + + VisualGPS + + CommLinx GPS recorder +
+ GPSMaster + + GPS Utility + + SparkFun GPS Datalogger +

snlen option

+ Max length of waypoint name to write. +

+This option specifies the maximum length to be used for waypoint names in +the GPWPL sentence. Longer names will be shortened to no more than this +length, but all waypoint names will remain unique. +

gprmc option

+ Read/write GPRMC sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPRMC sentences. The default is to read or write GPRMC sentences. To +disable GPRMC sentences, specify gprmc=0. +

+GPRMC sentences contain the "recommended mimimum" positional information, +including date and time, heading, and velocity. Note that they do not +include altitude. For altitude, you will have to include GPGGA sentences. +

gpgga option

+ Read/write GPGGA sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPGGA sentences. The default is to read or write GPGGA sentences. To +disable GPGGA sentences, specify gpgga=0. +

+GPGGA sentences contain the location and quality of the GPS position fix. +

gpvtg option

+ Read/write GPVTG sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPVTG sentences. The default is to read or write GPVTG sentences. To +disable GPVTG sentences, specify gpvtg=0. +

+GPVTG sentences contain information about the heading and the speed at the +time of the fix. They do not contain any location information; for that +you will need either or both of GPGGA or GPRMC. +

gpgsa option

+ Read/write GPGSA sentences. +

+This option tells GPSBabel whether to read (on input) or write (on output) +GPGSA sentences. The default is to read or write GPGSA sentences. To +disable GPGSA sentences, specify gpgsa=0. +

+GPGSA sentences contain information on the quality of the positional fix +and the individual satellites from which it was derived. However, GPSBabel +neither reads nor writes the individual satellite data. On input, the +satellite fields are ignored and on output they are left blank. +

date option

+ Complete date-free tracks with given date (YYYYMMDD).. +

+On input, track points with times but no dates will have this date applied. +

+This is necessary because some NMEA sentences contain times but no dates. If +this option is not specified and the date cannot be determined from one or +more of the available NMEA sentences, the tracks will be discarded. +

get_posn option

+ Return current position as a waypoint. +

This options, when specified, returns the current position as a single +waypoint. +

pause option

+ Decimal seconds to pause between groups of strings. +

+This option tells GPSBabel to pause between individual track records when +used on output. This may be used with appropriate external software or +hardware to simulate a GPS receiver for testing purposes. On Unix, for +example, you may use a named pipe to feed the output from GPSBabel to gpsd. +

+If a value for this option is specified, it is in seconds and it may be +either a whole number of seconds or a fraction (e.g. 0.5 for a 1/2 second +pause between trackpoints.) +

+If this option is specified without a value, the time between adjacent +trackpoints will be computed and used for the length of the pause. That is, +if your trackpoints are 5 seconds apart, GPSBabel will pause 5 seconds +between trackpoints. +

+Note that very long tracks may be subject to clock drift, as GPSBabel does +not take into account the amount of time it may take to write the NMEA +sentences. Also, there is no guarantee that it will pause for exactly the +specified number of seconds between samples; different operating systems +will allow greater or lesser precision for timers, so actual precision may +be as much as plus or minus 100 milliseconds. +

+If you are using this option with compressed or simplified tracks from +your handheld GPS receiver, you might find the +interpolate filter useful. +

baud option

+ Speed in bits per second of serial port (baud=4800). +

+To the "nmea" module, the "baud" option specifies the baud rate of the +serial connection when used with the real-time tracking option. +

OziExplorer (ozi)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

OziExplorer Waypoint Format - Another CSV format file. +Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex +Mottram

snlen option

+ Max synthesized shortname length. +

snwhite option

+ Allow whitespace synth. shortnames. +

snupper option

+ UPPERCASE synth. shortnames. +

snunique option

+ Make synth. shortnames unique. +

wptfgcolor option

+ Waypoint foreground color. +

wptbgcolor option

+ Waypoint background color. +

PalmDoc Output (palmdoc)

+ This format can... +

  • + write waypoints +

+

+PalmDoc output is similar to Text +output, except that it generates a Palm Database (PDB) file suitable for +use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and +others. The resulting file also contains bookmarks to make it easy to jump +to a particular waypoint. +

+The following command line reads a GPX file with Groundspeak extensions +and writes a Palm document with encrypted hints and logs: +

gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb

nosep option

+ No separator lines between waypoints. +

+To suppress the dashed lines between waypoints, use this option. +

dbname option

+ Database name. +

+This option specifies the internal name for the document. This is the name +that appears in your document reader, not the name of the file that is created +on your computer. +

encrypt option

+ Encrypt hints with ROT13. +

+Use this option to encrypt hints from Groundspeak GPX files. +

logs option

+ Include groundspeak logs if present. +

+Use this option to include Groundspeak cache logs in the created document. +

bookmarks_short option

+ Include short name in bookmarks. +

+If you would like the generated bookmarks to start with +the short name for the waypoint, specify this option. +

+This is particularly useful when used in combination with the 'sort' +filter. +

PathAway Database for Palm/OS (pathaway)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

PathAway is a Palm software designed for handling "most" +GPS devices (including BlueTooth). In this time (I mean 2005) a free +tool to convert this database is located on the homepage of PathAway +(www.pathaway.com). But I've read there ... for windows and the output +formats are also very limited. +

date option

+ Read/Write date format (i.e. DDMMYYYY). +

+This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYMMDD". +

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

deficon option

+ Default icon name. +

snlen option

+ Length of generated shortnames. +

Quovadis (quovadis)

+ This format can... +

  • + read and write waypoints +

+

QuoVadis for Palm OS marcosoft.com is a program for +Palm/OS. Working with record definitions provided by MarcoSoft and +further experimentation by Bruce Thompson and "Fuzzy" from the +Geocaching Forums to nail down the format precisely.

Should work fine for import and export.

One thing of note, QuoVadis stores all waypoints in a +single Palm Database without using categories. This means that it may +be difficult to keep personal waypoints separate from generated +waypoints. What Bruce recommends is taking the QuoVadisMarkerDB.PDB +file synced down from your Palm Powered device and extract the +waypoints you personally set to a GPX file. Then using GPSBabel's +joining capabilities generate a new PDB file from the personal file +and the other waypoint files of interest.

Currently the selection of icons to display and the scale +at which to display them is hardcoded. Also there is no support for +notes associated with waypoints. This will be addressed in a future +revision.

dbname option

+ Database name. +

+This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. +

See You flight analysis data (cup)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ This format supports flight analysis data from the + See You + program. +

+ Position information is preserved, but the aviation-specific + information such as runway length and airport frequency, are + written as blanks and ignored on read. +

+ Tasks are not supported. +

Sportsim track files (part of zipped .ssz files) (sportsim)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

+ With this format we support Sportsim trackfiles located in zipped .ssz archives. +

+ Currently we cannot read zipped files directly with GPSBabel. So you have + to extract the archive before you can use any file. The trackfiles have .txt extensions. +

+From the Sportsim homepage: +

+ Sportsim provide software applications and web-based graphically + simulated performance information and image solutions to outdoor active people. +

Suunto Trek Manager (STM) .sdf files (stmsdf)

+ This format can... +

  • + read and write tracks +

  • + read and write routes +

+

+ This format supports the .sdf files from the Suunto product family + 'Suunto Trek Manager', 'Suunto Ski Manager' and 'Suunto Sail Manager'. + The contents of the sdf file depends on the used product and can + be one route or one track. Thatswhy when you want to use sdf on the + output side you have to use the + -r OR the -t option. This will tell + GPSBabel which type of data should be written. +

+ Currently we can read the following file types: +

4 = M9 TrackLog
5 = Route
28 = X9 TrackLog

+

+

gpsbabel -i gpx -f some-routes.gpx -r -o stmsdf,index=3 -F single-route.sdf

+

+ Suunto Website +

index option

+ Index of route (if more the one in source). +

+ Convert route number 'index' from source into sdf format. +

+ We have a lot of more expressive formats thats support more than one route. + At this place sdf files are limited to only one single route. With option index + you can specify which route from source should be converted. +

+ Our default index is 1. +

+ This example will convert route number two and three into separate sdf files: +

+		gpsbabel -i gdb -f routes.gdb -r -o stmsdf,index=2 -F route-one.sdf -r -o stmsdf,index=3 -F route-three.sdf
+	

+

Suunto Trek Manager (STM) WaypointPlus files (stmwpp)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

+This format supports the Suunto Trek Manager (STM) WaypointPlus format. +This is a simple format with coordinates and a time stamp. Route points +also have a short name. A single file may only contain one route or one +track. +

+Suunto Website +

index option

+ Index of route/track to write (if more the one in source). +

+Because the format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains three routes, you may +use this option to write them one at a time to individual files. +

gpsbabel -i gpx -f routes.gpx -o stmwpp,index=1 -F route1.txt -o stmwpp,index=2 -F route2.txt -o stmwpp,index=3 -F route3.txt

Tab delimited fields useful for OpenOffice, Ploticus etc. (openoffice)

+ This format can... +

  • + read and write waypoints +

+

+This format is derived from the xcsv +format, so it has all of the same options as that format. +

Tab seperated export-all (except geocaching data) file +format. Intended to serve as source for number-processing +applications like OpenOffice, Ploticus and others. Tab was chosen as +delimiter because it is a) supported by both OpenOffice and Ploticus +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich.

Textual Output (text)

+ This format can... +

  • + write waypoints +

+

This is a simple human readable version of the data file, +handy for listings of any type of waypoint files. +

The following command line reads a GPX file with +Groundspeak extensions and writes a text file with encrypted hints: +

gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt

nosep option

+ Suppress separator lines between waypoints. +

+To suppress the dashed lines between waypoints, use this option. +

encrypt option

+ Encrypt hints using ROT13. +

+Use this option to encrypt hints from Groundspeak GPX files. +

logs option

+ Include groundspeak logs if present. +

+Use this option to include Groundspeak cache logs in the created document. +

degformat option

+ Degrees output as 'ddd', 'dmm'(default) or 'dms'. +

+When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. +

altunits option

+ Units for altitude (f)eet or (m)etres. +

+This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. +

TomTom POI file (tomtom)

+ This format can... +

  • + read and write waypoints +

+

This format can read and write TomTom .ov2 (POI) files, +as used by the TomTom GO and TomTom Navigator. It has been tested +with an original TomTom GO running version 5.00 of the TomTom +software. There may be some records that confuse the input module - +if you have an example of such a record "in the wild", and you aren't +restricted from sharing it, we encourage you to post to the +gpsbabel-misc mailing list to contact a developer.

Note that in addition to the .ov2 file, you will need a +.bmp file for the icon. It should be 22x22 and 16 colors, and have +the same name (not including the extension) as the .ov2 file. +

TopoMapPro Places File (tmpro)

+ This format can... +

  • + read and write waypoints +

+

TopoMapPro Places File. Reads and writes places files for +use in TopoMapPro topomappro.com). As this file +type can store links other than web links, anything that is not a http +url will be discarded. Note that this does not do datum conversions, +so if your input file does not have WGS84/NZGD2000 data, your output +file won't either. Colour of waypoint icons defaults to red.

TrackLogs digital mapping (.trl) (dmtlog)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

+

+ This format can be used to convert files from + TrackLogs Digital Mapping. The files + have extension .trl and can contain waypoints and tracks. +

+ We have seen three different types of this format. Two are binary + and one is an XML based format. All three types are supported + by our reader. +

index option

+ Index of track (if more the one in source). +

+ Convert track number 'index' from source into dmtlog format. +

+ The known variants of Tracklog 'digital mapping' files supports only + one track per file. If you have more than one track in source + (f.e MapSource and many others can do such heavy things), you + can specify which track should by used for the conversion. +

+ The default index is 1 (the first track of a possible list of tracks). +

+ An example usage you can find at the ignrando format, + which uses option index in same manner. +

U.S. Census Bureau Tiger Mapping Service (tiger)

+ This format can... +

  • + read and write waypoints +

+

The U.S. Census Bureau provides online mapping facilities. +This format is described at: tiger.census.gov. +Do notice that this format is not the actual Tiger line mapping +records, but rather the interface to their online mapping +program.

nolabels option

+ Suppress labels on generated pins. +

This option tells GPSBabel to not generate labels on the pins. If +this is true, the description of the incoming waypoints are ignored and not +placed on the pins.

genurl option

+ Generate file with lat/lon for centering map. +

+genurl is a convenience option for generating the scaling paramaters +when accessing the Tiger servers. It will output the latitude, longitude, +height, and width parameters in a form suitable for use in the URL to generate +a map that will hold all the points to be displayed and is suitably scaled +and centered. +

For example: +

gpsbabel -i geo -f geocaching.loc -o tiger,genurl=tiger.ctr -F tiger.dat

+may create tiger.ctr with +

lat=36.042108&lon=-86.877408&ht=0.161172&wid=0.591771&iwd=768&iht=768

+ +After uploading tiger.dat to a public server, a request to +

 http://tiger.census.gov/cgi-bin/mapgen?murl=$THATFILE$(cat tiger.ctr)

+will return a gif file from the tiger server that's suitably scaled. + +

margin option

+ Margin for map. Degrees or percentage. +

This option specifies a margin around the maps for the genurl options. +The margin may be specified in either decimal degrees or as a +percentage.

+This option is most useful for ensuring there is adaequate space for +the label around the markers when generating automatically scaled maps. +

snlen option

+ Max shortname length when used with -s. +

+The snlen option controls the maximum length of names generated by the '-s' +option. It's particularly useful in Tiger maps to avoid the amount of clutter +generated by potentially lengthy labels on the markers. +

oldthresh option

+ Days after which points are considered old. +

This options allows you to control the threshold in days between +whether a pin is considered "new" (and thus potentially governed by the +'newmarker' option) or "old" (and thus potentially governed by the +'oldmarker' option). +

oldmarker option

+ Marker type for old points. +

This option specifies the pin to be used if a waypoint has a creation +time newer than 'oldthresh' days.

The default is "redpin".

newmarker option

+ Marker type for new points. +

This option specifies the pin to be used if a waypoint has a creation +time older than 'oldthresh' days.

The default is "greenpin".

suppresswhite option

+ Suppress whitespace in generated shortnames. +

+When set, this options tells the '-s' smartname generator to not allow +any spaces in the labels generated for markers. +

unfoundmarker option

+ Marker type for unfound points. +

xpixels option

+ Width in pixels of map. +

The xpixels argument lets you specify the number of pixels to be +generated by the Tiger server along the horizontal axis when using the +'genurl' option.

ypixels option

+ Height in pixels of map. +

The ypixels argument lets you specify the number of pixels to be +generated by the Tiger server along the vertical axis when using the +'genurl' option.

iconismarker option

+ The icon description is already the marker. +

This options signifies that the icon in the incoming format is to be used +without change in the generated Tiger output file. Without this option, +GPSBabel tries to color pins based on their creation time and certain +Geocaching traits when available.

Universal csv with field structure in first line (unicsv)

+ This format can... +

  • + read waypoints +

+

+ Unicsv examines the first line of a file to determine the field + order and field separator in that file. It is thus read-only format. +

+ If the first line contains any tabs, the data lines are assumed + to be tab separated. Otherwise the fields are assumed to be + separated by commas. +

+ The list of keywords include "lat", "lon", "desc", "name", + "notes", "alt", "utm z", "utm n", "utm e", and "url". + Fuller spellings (i.e. "longitude") may be used. +

+ A typical file may be: +

+	Name, Latitude, Longitude, Description 
+	GCEBB,35.972033,-87.134700,Mountain Bike Heaven by susy1313
+ 	GC1A37,36.090683,-86.679550,The Troll by a182pilot & Family
+	

+

Vcard Output (for iPod) (vcard)

+ This format can... +

  • + write waypoints +

+

The vCard output is intended to be in a format that +enables waypoints to be viewed with an Apple iPod. This is achieved by +mapping waypoint fields into vCard fields that can be displayed as +'Contacts' on the iPod. With the iPod mounted as a hard disk (see your +iPod manual for instructions), the resulting VCF file should be moved +into the iPod 'Contacts' folder. As an alternative, Mac OS X users may +prefer to drag the VCF file into their address book and synchronize +with the iPod using iSync. +

encrypt option

+ Encrypt hints using ROT13. +

+By default geocaching hints are unencrypted; use this option to encrypt them. +

Vito Navigator II tracks (vitosmt)

+ This format can... +

  • + read and write waypoints +

  • + read and write tracks +

  • + read and write routes +

+

Vito Navigator II is a Pocket PC GPS application. This +format reads a Vito Navigator II .SMT track file and can work in +either waypoint or track mode. The speed, heading and Dilution of +Position data is written in the notes field.

Support for writing .SMT tracks is very experimental and +may crash VitoNavigator II on the Pocket PC.

WiFiFoFum 2.0 for PocketPC XML (wfff)

+ This format can... +

  • + read waypoints +

+

WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs.

It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session.

All WiFi-specific elements are written in the description field, similar to the netstumbler format.

aicicon option

+ Infrastructure closed icon name. +

aioicon option

+ Infrastructure open icon name. +

ahcicon option

+ Ad-hoc closed icon name. +

ahoicon option

+ Ad-hoc open icon name. +

snmac option

+ Shortname is MAC address. +

Wintec WBT-100/200 Binary file format (wbt-bin)

+ This format can... +

  • + read tracks +

+

File protocol for the Wintec WBT-200™ +GPS data logger. This format reads the binary file format created +by Wintec's Windows application.

+Wintec WBT-200 +

Example 3.3. Command showing conversion of a Wintec binary file to GPX

gpsbabel -i wbt-bin -f tracks.bin -o
+gpx -F out.gpx

Wintec WBT-100/200 GPS Download (wbt)

+ This format can... +

  • + read tracks +

+

Serial download protocol for the Wintec WBT-200™ GPS data logger. Although untested it is expected that this will also support the WBT-100.

+Wintec WBT-200 +

Example 3.4. Command showing WBT-200 download and erase over Bluetooth on Mac OS X

gpsbabel -i wbt,erase -f /dev/cu.WBT200-SPPslave-1 -o gpx -F out.gpx

erase option

+ Erase device data after download. +

This option erases the track log from the device after download.

Yahoo Geocode API data (yahoo)

+ This format can... +

  • + read waypoints +

+

+This format reads output from the +Yahoo geocoding API. +This feature of GPSBabel makes it easy to get geocoded results from +Yahoo into your favorite mapping program, GPS receiver, or other format. +

addrsep option

+ String to separate concatenated address fields (default=", "). +

+This option specifies the string GPSBabel should use to separate the parts +of the street address. Since most other formats supported by GPSBabel do +not support street addresses, the street address fields from the Yahoo file +are concatenated into the waypoint "notes" field. +

+The default value for this option is a comma followed by a space (", "). +



[1] This unit uses GPX format, not Garmin protocol. Therefore one should communicate with it by reading and writing GPX files instead of using this format.

Chapter 4. Data Filters

GPSBabel supports data filtering. Data filters are + invoked from the command line via the '-x' option. It should be + noted that data filters are invoked in the internal pipeline at + the point that corresponds to their position on the + command. This implies that specifying a filter before reading + any data ('-x <filter> -f <file>'), despite being + legal, will not have any effect. The advantage is that filters + can be used intermittently between several variations of input + and output functions. It should also be noted that filtering + data from different input types can sometimes produce + undesirable results due to differences in the native data + formats. +

Beware that most filters only apply to a certain kind of + data. This is usually indicated below by referring to points, + tracks or routes in the first sentence which describes each + filter or in the table at gpsbabel.org + . +

Include Only Points Inside Polygon (polygon)

+The polygon filter includes points if they are inside +of a polygon. A polygon file looks like an +arc file, except +that the arc it describes must be a closed cycle. That is, +for a simple polygon, the first and last points must be the +same. Here's a square: +

+# A square (not really) polygon
+41.0000       -85.0000
+41.0000       -86.0000
+42.0000       -86.0000
+42.0000       -85.0000
+41.0000       -85.0000
+

+Polygons may include islands and holes. To include an +island or a hole, just append it to the main polygon. +

+# A square polygon with a triangular hole
+41.0000       -85.0000
+41.0000       -86.0000
+42.0000       -86.0000
+42.0000       -85.0000
+41.0000       -85.0000
+# The hole begins here
+41.5000       -85.5000
+41.6000       -85.5000
+41.6000       -85.6000
+41.5000       -85.5000
+

+As with the arc filter, you define a polygon by +giving the name of the file that contains it, using +the file option. +

+Note that this filter currently will not work properly +if your polygon contains one or both poles or if it spans the +line of 180 degrees east or west longitude. +

Example 4.1. Using the polygon filter

+Suppose you have a polygon file that defines the border of your county, +called mycounty.txt. This command line will give you only the points +in your county: +

gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt -o mapsend -F 2.wpt

Example 4.2. Using the polygon and arc filters to find points in or nearly in a +polygon

+Because the polygon and arc filters use +the same file format, you can use them together to find all points that are +"in or nearly in" a polygon. This can be useful if your waypoints or the +boundaries of your polygon are not quite perfect, so you want to provide a +buffer zone around it in case there are points nearby that should be in the +polygon but aren't quite. +

+gpsbabel -i gpx -f points.gpx -x stack,push -x polygon,file=mycounty.txt 
+-x stack,swap -x arc,file=mycounty.txt,distance=1k -x stack,pop,append 
+-x duplicate,shortname -o gpx -F nearmycounty.gpx
+

+This command makes a copy of the points, finds the ones that are in your +your county, swaps that result with the copy of the original set of points, +finds the ones from that set that are within 1 km of the border of the county, +puts the two lists together, and then filters out any points that appear twice +(This step is necessary because points inside the county but near the county +line will be kept by both the polygon and the arc filter.) +

file option

+ File containing vertices of polygon. +

+This option is required. +

+This option specifies the name of the file containing the polygon to use for +filtering. The format of the file is as described above. +

+GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. Afterward, you will +need to make sure that the first point and the last point in the +file are the same, as the polygon filter depends on that. You can do so +with any text editor. +

exclude option

+ Exclude points inside the polygon. +

+When this option is specified, the usual sense of the polygon filter is +reversed. That is, points that are inside the polygon are discarded +while points that are further away are kept. +

Include Only Points Within Distance of Arc (arc)

+This filter keeps or removes waypoints based on their proximity to an arc, +which is a series of connected line segments similar to a route or a track +but without any associated data other than the coordinates. +

+The arc is defined in a file whose name must be provided with the +file. That file contains pairs of coordinates for the +vertices of the arc, one coordinate pair per line. Comments may be +included by preceding them with a '#' character. An arc file looks +something like this sample: +

	  
+# Lima Road/SR3 north of Fort Wayne, Indiana 	  
+41.150064468    -85.166207433 	  
+41.150064468    -85.165371895 	  
+41.149034500    -85.165157318 	  
+41.147832870    -85.164771080 	  
+41.146631241    -85.164384842 	  
+41.144270897    -85.163655281 	  
+41.141953468    -85.162882805
+

+An arc file may optionally contain gaps in the arc. You may specify +such a gap by inserting a line containing "#break" either on a line by +itself or after the coordinates of the starting point of the new arc segment. +

Example 4.3. Using the arc filter

+Assuming the arc above is in a file called +lima_rd.txt, the following command line +would include only points within one mile of the section of Lima Road +covered by the arc. +

gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 -o mapsend -F 2.wpt

file option

+ File containing vertices of arc. +

+This option is required. +

+This option specifies the name of the file containing the arc to use for +filtering. The format of the file is as described above. +

+GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. +

distance option

+ Maximum distance from arc. +

+This option is not required, but if it is not specified the distance +defaults to zero miles, which isn't very useful. +

+This option specifies the maximum distance a point may be from the arc +without being discarded. Points that are closer to the arc are kept, while +points that are further away are discarded. +

+Distances may be specified in miles (3M) or kilometers (5K). If no units +are specified, the distance is assumed to be in miles. +

exclude option

+ Exclude points close to the arc. +

+When this option is specified, the usual sense of the arc filter is reversed. +That is, points that are closer than distance are discarded +while points that are further away are kept. +

points option

+ Use distance from vertices not lines. +

+When this option is specified, only points that are within the specified +distance of one of the vertices of the arc are kept. This differs from the +normal mode of operation in that in the normal mode, points that are close to +the lines between points are also kept. +

+This option makes the arc filter act like a multi-point version of the +radius filter. +

Include Only Points Within Radius (radius)

+This filter includes or excludes waypoints based on their proximity to a +central point. All waypoints more than the specified distance from the +specified point will be removed from the dataset. +

+By default, all remaining points are sorted so that points closer to the +center appear earlier in the output file. +

Example 4.4. Using the radius filter to find points close to a given point

This example command line would include only points within 1 1/2 miles + of N30.000 W 90.000

gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 -o mapsend -F 2.wpt

lat option

+ Latitude for center point (D.DDDDD). +

+This option is required. +

+This option specifies the latitude of the central point in decimal degrees. +South latitudes should be expressed as a negative number. Valid values for +this option are from -90 to 90. +

lon option

+ Longitude for center point (D.DDDDD). +

+This option is required. +

+This option specifies the longitude of the central point in decimal degrees. +West longitudes should be expressed as a negative number. Valid values for +this option are from -180 to 180. +

distance option

+ Maximum distance from center. +

+This option is required. +

+This option specifies the maximum distance a point may be from the central +point in order to remain in the dataset. Points closer than this distance +will be kept and points further away will be removed (unless the +exclude option is specified.) +

+Distances may be expressed in miles (3M) or kilometers (4K). If no units +are provided, the distance is assumed to be in miles. +

exclude option

+ Exclude points close to center. +

+If this option is included, the action of the radius filter will be reversed: +points within the given distance will be removed, and points further away +will be kept. +

nosort option

+ Inhibit sort by distance to center. +

+If this option is specified, the radius filter will not sort the remaining +points by distance from the center. They will remain in whatever order they +were originally. +

maxcount option

+ Output no more than this number of points. +

+This option specifies the maximum number of points that the radius filter may +keep. If there are more than this number of points within the specified +distance of the center, the more distant points will be discarded even though +they are within the specified distance. If this option is not specified, +all points are kept regardless of how many there are. +

+Note that if the nosort option is also specified, this +option will instead keep points based on their position within the input +file rather than on their distance from the center. This may or may not be +what you want. +

+Note, too, that this option may be used with the exclude +option, but the results might not be what you expect. In particular, the +results will not be the same as if you had kept all of the points you'd +otherwise throw away. You will still get no more than +maxcount points, but they will all be at least +distance away from the center. (And possibly sorted.) +

asroute option

+ Put resulting waypoints in route of this name. +

+This option specifies the name of a route. If this option is specified, the +radius filter puts all points that are kept into a route with the given name. +The order of points in the route is by distance from the center (unless the +nosort option is also specified.) +

+Note that this route is not necessarily the most efficient route to visit +all of the points. In fact, for some data sets, it might be the least +efficient route. +

Interpolate between trackpoints (interpolate)

+This filter modifies any tracks so that either the distance or the time +between consecutive points is no less than the specified interval. Where +points are missing, the filter fills them in by following a straight +line (actually a great circle) between the adjacent points. You +must specify either the +distance or the time option. +

Example 4.5. Using the interpolate filter

+This command line reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 10 seconds apart: +

gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -F newtrack.gpx

+This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 15 kilometers apart: +

gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -F newtrack.gpx

+This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 2 miles apart: +

gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -F newtrack.gpx

time option

+ Time interval in seconds. +

+This option specifies the maximum allowable time interval between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. +

+This value is always specified in units of seconds. +

+Either this option or the distance must be specified. +

distance option

+ Distance interval in miles or kilometers. +

+This option specifies the maximum allowable distance between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. +

+This value may be specified in units of miles (3M) or kilometers (5K). If +no units are specified, the units are assumed to be miles. +

+Either this option or the time must be specified. +

route option

+ Interpolate routes instead. +

+If this option is specified, the interpolate filter interpolates routes +rather than tracks. Because route points do not have time stamps, it is an +error to use this option with the time option. +

Manipulate track lists (track)

+WARNING: This filter always drops empty tracks. +

+This filter performs various operations on track data. +

move option

+ Correct trackpoint timestamps by a delta. +

+This option changes the time of all trackpoints. This might be useful if +your track must be moved by one or more hours because of an incorrect +time zone. +

Example 4.6. Time-shifting a track with the track filter

+The following command line will shift all tracks to be one hour later. +

gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx

pack option

+ Pack all tracks into one. +

+This option causes all tracks to be appended to one another to form a single +track. This option does not work if any two tracks overlap in time; in that +case, consider using the merge option. +

+This option is most useful for rejoining tracks that might have +been interrupted by an equipment malfunction or an overnight stop. +

+If no other option is given to the track filter, this option is assumed. +

split option

+ Split by date or time interval (see README). +

The input track will be split into several tracks + depending on date of track points. If there is more than one + track, use the pack option before before using this. To + split a single tracks into separate tracks for each day and + name them, use this: +

+gpsbabel -t -i gpx -f in.gpx -x \
+   track,split,title="ACTIVE LOG \
+    # %Y%m%d" -o gpx -F out.gpx

If the input has multiple tracks, pack them together before +splitting them back apart per day thusly:

     	    
+gpsbabel -t   -i gpx -f in.gpx  \
+     -x track,pack,split,title="ACTIVE LOG # %D"  	\
+     -o gpx -F out.gpx

Additionally you can add an interval to the split + option. With this the track will be split if the time + between two points is greater than this parameter. The + interval must be numeric and can be int days, hours, minutes + or seconds, expressed as one of the character "d", "h", "m", + or "s". If no trailing character is present, the units are + assumed to be in seconds. +

For example, to split a track based on an four hour + interval, use this:

            
+gpsbabel -t \ 
+     -i gpx -f in.gpx \ 
+     -x track,pack,split=4h,title="LOG # %c" \ 
+     -o gpx -F out.gpx
+

sdistance option

+ Split by distance. +

The input track will be split into several tracks + if the distance between successive track points + is greater than the distance given as a parameter. + The distance must be numeric and can be in miles or kilometers, + expressed as one of the character "k", or "m". + If sdistance is given no parameters, this option has the same + effect as the split option without parameters. If there is more + than one track, + use the pack option before before using this.

For example, to split the track if the distance between + points is greater than 100 meters, use this:

+gpsbabel -t \
+     -i gpx -f in.gpx \
+     -x track,pack,sdistance=0.1k" \
+     -o gpx -F out.gpx
+

The sdistance option can be combined with the split option. + The track then will be split only if both time and distance + interval exceeds the supplied values. This technique can be used to + filter out gaps from + the tracklog. The gap is kept only if the gps device is without + signal for longer time than that given and during that time it moves + a distance over that given. + This example splits the track + if the device is without signal for at least 5 minutes + and during this time moves more than 300 meters:

+gpsbabel -t \
+     -i gpx -f in.gpx \
+     -x track,pack,sdistance=0.3k,split=5m \
+     -o gpx -F out.gpx
+

merge option

+ Merge multiple tracks for the same way. +

+This option puts all track points from all tracks into a single track +and sorts them by time stamp. Points with identical time stamps will be +dropped. +

Example 4.7. Merging tracks with the track filter

+Suppose you want to merge tracks recorded with two different GPS devices +at the same time. To do that, use this command line: +

gpsbabel -t -i gpx -f john.gpx -i gpx -f doe.gpx -x track,merge,title="COMBINED LOG" -o gpx -F john_doe.gpx

name option

+ Use only track(s) where title matches given name. +

+With the name option you can filter out a track by title. +

+The comparison is always non-case-sensitive. Wildcards are allowed. +

start option

+ Use only track points after this timestamp. +

+This option is used along with the stop to discard +trackpoints that were recorded outside of a specific period of time. +This option specifies the beginning of the time period. +

+If this option is not specified, the time period is assumed to begin at the +dawn of time or January 1, 1970, whichever was later. The time for this +option is expressed in UTC. +

+The value of this option must be in the form of YYYYMMDDHHMMSS, but it is +not necessary to specify the smaller time units if they are not needed. +That is, if you only care about points logged between 10 AM and 6 PM on a +given date, you need not specify the minutes or seconds. +

Example 4.8. Extracting a period of time with the track filter

+To get only the parts of a track that were mapped on 20 July 2005 +between 10 AM and 6 PM, use this command line: +

gpsbabel -t -i gpx -f in.gpx -x track,start=2005072010,stop=2005072018 -o gpx -F out.gpx 

stop option

+ Use only track points before this timestamp. +

+This option is used in conjunction with the start option to +discard all trackpoints outside of a given period of time. This option +defines the end of the time period. +

+If this option is not specified, the time period is assumed to end at the +end of civilization as we know it or the year 2038, whichever comes first. +The time for this option is expressed in UTC. +

+See the start option for the format of this value and an +example of usage. +

title option

+ Basic title for new track(s). +

+This option specifies a title for tracks generated by the track filter. +By default, the title of the new track is composed of the start time of +the track appended to this value. +

+If this value contains a percent (%) character, it is treated as a format +string for the POSIX strftime function, allowing custom time-based +track names. +

fix option

+ Synthesize GPS fixes (PPS, DGPS, 3D, 2D, NONE). +

+This option sets the GPS fix status for all trackpoints to the specified +value. Valid values for this option are PPS, DGPS, 3D, 2D, or NONE. +

+This option is most useful when converting from a format that doesn't +contain GPS fix status to one that requires it. +

course option

+ Synthesize course. +

+This option computes (or recomputes) a value for the GPS heading at each +trackpoint. This is most useful with trackpoints from formats that don't +support heading information or for trackpoints synthesized by the +interpolate +filter. The heading at each trackpoint is simply the course from the +previous trackpoint in the track. The first trackpoint in each track +is arbitrarily assigned a heading of 0 degrees. +

speed option

+ Synthesize speed. +

+This option computes a value for the GPS speed at each trackpoint. +This is most useful with trackpoints from formats that don't support +speed information or for trackoints synthesized by the +interpolate +filter. The speed at each trackpoint is the average speed from the +previous trackpoint (distance divided by time). The first trackpoint +in each track is assigned a speed of "unknown." +

Rearrange waypoints by resorting (sort)

+This filter sorts waypoints into alphabetical order by the selected field. +You must specify exactly one of the options. +

gcid option

+ Sort by numeric geocache ID. +

+If the data contains Groundspeak geocache IDs, this option causes the +waypoints to be sorted in alphabetical order by geocache ID. +

+This option is not valid in combination with any other option. +

shortname option

+ Sort by waypoint short name. +

+This option causes the waypoints to be sorted in alphabetical order by +short name. +

+This option is not valid in combination with any other option. +

description option

+ Sort by waypoint description. +

+This option causes the waypoints to be sorted in alphabetical order by +description. +

+This option is not valid in combination with any other option. +

time option

+ Sort by time. +

+This option causes the waypoints to be sorted in chronological order by +creation time. +

+This option is not valid in combination with any other option. +

Remove all waypoints, tracks, or routes (nuketypes)

+There are three main types of data that GPSBabel deals with: +waypoints, tracks, and routes. The nuketypes filter allows +removing all the data of any or all of those three types. +

Example 4.9. Filtering data types with nuketypes

+If you have a GPX file that contains routes, tracks, and +waypoints and you want a GPX file that contains only tracks, +you may use this filter to remove the waypoints and the routes +with this command: +

gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx

waypoints option

+ Remove all waypoints from data stream. +

+This option causes the nuketypes filter to discard all waypoints that are not +associated with a track or route. +

tracks option

+ Remove all tracks from data stream. +

+This option causes the nuketypes filter to discard all track data. +

routes option

+ Remove all routes from data stream. +

+This option causes the nuketypes filter to discard all route data. +

Remove Duplicates (duplicate)

+The duplicate filter is designed to remove duplicate points based on their +short name (traditionally a waypoint's name on the GPS receiver), and/or +their location (to a precision of 6 decimals). This filter supports two +options that specify how duplicates will be recognized, +shortname and location. +Generally, at least one of these options is required. +

Example 4.10. Using the duplicate filter to suppress points with the same + name and location

+ This command line removes points that have duplicate short names + and duplicate locations. The result would be a + gpx file that more than likely + contains only unique points and point data. +

 gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname -o gpx -F merged_with_no_dupes.gpx

shortname option

+ Suppress duplicate waypoints based on name. +

+This option is the one most often used with the duplicate filter. This +option instructs the duplicate filter to remove any waypoints that share +a short name with a waypoint that has come before. This option might be +used to remove duplicates if you are merging two datasets that were +each created in part from a common ancestor dataset. +

location option

+ Suppress duplicate waypoint based on coords. +

+This option causes the duplicate filter to remove any additional waypoint +that has the same coordinates (to six decimal degrees) as a waypoint that +came before. This option may be used to remove duplicate waypoints if the +names are not expected to be the same. It also might be used along with the +shortname option to remove duplicate waypoints if the names +of several unrelated groups of waypoints might be the same. +

all option

+ Suppress all instances of duplicates. +

+When this option is specified, GPSBabel will remove all instances of a +duplicated waypoint, not just the second and subsequent instances. If +your input file contains waypoints A, B, B, and C, the output file will +contain waypoints A, B, and C without the all option, +or just A and C with the all option. +

Example 4.11. Using the duplicate filter to implement an "ignore list."

+This option may be used to implement an "ignore list." In the following +example, the duplicate filter is used to remove a list of waypoints to be +ignored from a larger collection of waypoints: +

gpsbabel -i gpx -f waypoints.gpx -i csv -f to_ignore.csv -x duplicate,shortname,all -o gpx -F filtered.gpx

correct option

+ Use coords from duplicate points. +

+This option is used to change the locations of waypoints without losing any +of the other associated information. When this option is specified, the +latitude and longitude from later duplicates will replace the latitude and +longitude in the original waypoint. +

+As an example, this option may be used to adjust the locations of "puzzle" +geocaches in a Groundspeak pocket query: +

Example 4.12. Using the duplicate filter to correct the locations of "puzzle" +geocaches

gpsbabel -i gpx -f 43622.gpx -i csv -f corrections.csv -x duplicate,shortname,correct -o gpx -F 43622-corrected.gpx

+After this command is run, the waypoints in the output file will have all +of the descriptive information from 43622.gpx, but +waypoints that were also found in corrections.csv +will have their coordinates replaced with the coordinates from that file. +

Remove Points Within Distance (position)

+This filter removes points based on their proximity to each other. A +point is removed if it is within the specified distance of a point that +has come before. +

Example 4.13. Using the position filter to suppress close points

+The following command removes multiple points that are within +one foot of each other, leaving just one. +

gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f -o mapsend -F 3.wpt

distance option

+ Maximum positional distance. +

+This option specifies the minimum allowable distance between two points. If +two points are closer than this distance, only one of them is kept. +

+Distances may be expressed in feet (30f) or meters (10m). If no unit is +specified, the distance is assumed to be in feet. +

all option

+ Suppress all points close to other points. +

+This option causes the position filter to remove all points that are within +the specified distance of one another, rather than leaving just one of them. +

+This option may be used to entirely remove clusters of points. +

Remove unreliable points with high hdop or vdop (discard)

+This filter is used to "fix" unreliable GPS data by discarding points +with HDOP and/or VDOP above a specified limit. HDOP and VDOP are +measures of the best possible horizontal or vertical precision +for a given configuration of GPS satellites. +

Example 4.14. Using the discard filter

 gpsbabel -i gpx -f in.gpx -x discard,hdop=10,vdop=20,hdopandvdop -o gpx -F out.gpx

Contributed by Tobias Minich.

hdop option

+ Suppress waypoints with higher hdop. +

+This option specifies the maximum allowable Horizontal Dilution of +Precision (HDOP). By default, any point with an HDOP in excess of +this value will be discarded regardless of its VDOP, but see +hdopandvdop. +

vdop option

+ Suppress waypoints with higher vdop. +

+This option specifies the maximum allowable Vertical Dilution of +Precision (VDOP). By default, any point with an VDOP in excess of +this value will be discarded regardless of its HDOP, but see +hdopandvdop. +

hdopandvdop option

+ Link hdop and vdop supression with AND. +

+If this option is used, only points that exceed both the maximum +allowable HDOP and the maximum allowable VDOP will be discarded. This +option requires that both the hdop and +vdop options be specified. +

Reverse stops within routes (reverse)

The reverse filter is used to reverse tracks and routes. + It's mostly useful for those few formats where track/route + sequence matters and there isn't a way to reverse them using + the program itself.

The reversal is performed in the laziest way possible. + Timestamps are kept with the original waypoints so the + resulting track or route will have the interesting + characteristic that time runs backwards. This tends to make + Magellan Mapsend, in particular, do a wierd thing and place + each waypoint on a separate day. +

Additionally, if you're using this to reverse a route + that navigates, say, an exit ramp or a one way street, you + will be in for unpleasant ride. application cares about + timestamps +

Save and restore waypoint lists (stack)

+This filter is designed to solve advanced problems that involve shuffling +multiple lists of waypoints, tracks, or routes. +

+The stack filter can be used to save the current state of the entire +collection of data. That state is placed on top of a stack of collections, +so you can simultaneously have as many stored collections of data as you +can fit in your computer's memory. +

+ The stack filter can be used in conjunction with other + filters to implement a "union" or "logical or" functionality. + The basic idea is to use the stack to store copies of the + original list of waypoints, then use the 'swap' function to + replace each copy with a filtered list. Finally, append all + of the filtered lists to create one big list, which is then + output. The following example finds a list of all points + that are either inside county A or inside county B. Any + points that are inside both counties are duplicated (but the + duplicates can be removed with the DUPLICATE filter; see + above.) +

           
+gpsbabel -i gpx -f in.gpx \
+         -x stack,push,copy \
+         -x polygon,file=county_a.txt \    
+         -x stack,swap \
+         -x polygon,file=county_b.txt \
+         -x stack,pop,append \
+         -o gpx -F out.gpx
+

This example reads a large list of waypoints and + extracts the points within 20 miles of each of two cities, + writing the waypoint descriptions into two different PalmDoc + files and exporting all of the points to the GPS receiver: +

           
+gpsbabel -i gpx -f indiana.gpx \
+         -x stack,push,copy \
+         -x radius,lat=41.0765,lon=-85.1365,distance=20m \
+         -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb \
+         -x stack,swap \
+         -x radius,lat=39.7733,lon=-86.1433,distance=20m \
+         -o palmdoc,dbname=Indianapolis -F indianapolis.pdb \
+         -x stack,pop,append \
+         -o magellan -F fwaind.wpt
+

push option

+ Push waypoint list onto stack. +

+This is one of three "primary" options to the stack filter. +

+When this option is specified, the current state is pushed onto the top of +the stack. By default, the current state is then cleared, but the +copy option can be used to cause it to be saved. +

pop option

+ Pop waypoint list from stack. +

+This is one of three "primary" options to the stack filter. +

+This option "pops" the collection of data from the top of the stack. +By default, the saved state replaces the current state, but see the +discard and append options for +alternatives. +

swap option

+ Swap waypoint list with <depth> item on stack. +

+This is one of three "primary" options to the stack filter. +

+When this option is specified, the current state is swapped with a saved +state from the stack. By default, it is swapped with the top of the stack, +but the depth can be used to specify a different saved +state. +

copy option

+ (push) Copy waypoint list. +

+This option is only valid when used with the push option. +When this option is specified, a copy of the current state is pushed onto +the stack but the current state is left unchanged. Otherwise, the push +operation clears the current data collection. +

append option

+ (pop) Append list. +

+This option is only valid in conjunction with the pop. +When it is specified, the topmost collection of data from the stack is +appended to the current collection of data. +

discard option

+ (pop) Discard top of stack. +

+This option is only valid when used with the pop option. +When this option is specified, the popped state is discarded and the current +state remains unchanged. +

replace option

+ (pop) Replace list (default). +

+This option is only valid when used with the pop option. +This is the default behavior of the pop option, so you +should never need to specify it, but it is included for the sake of +readability. When this option is specified, the popped state replaces +the current state. +

depth option

+ (swap) Item to use (default=1). +

+This option is only valid when used along with the swap +option. If specified, it indicates which item on the stack should be +swapped with the current state. The default value is 1, which corresponds +to the top of the stack. +

Simplify routes (simplify)

+The Simplify filter is used to simplify routes and tracks for use with +formats that limit the number of points they can contain or just to +reduce the complexity of a route. +

+The filter attempts to remove points from each route until the number +of points or the error is within the given bounds, while also attempting +to preserve the shape of the original route as much as possible. +

+The quality of the results will vary depending on the density of points +in the original route and the length of the original route. +

+For example, suppose you have a route from Street Atlas 2003 that you +wish to use with a Magellan GPS receiver that only supports up to 50 points +in a route: +

gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 -o magellan  -F grocery.rte

count option

+ Maximum number of points in route. +

+This option specifies the maximum number of points which may appear in the +simplified route. For example, if you specify "count=50", all resulting +routes will contain 50 points or fewer. +

+You must specify either this option or the error option. +

error option

+ Maximum error. +

+This option specifies the maximum allowable error that may be introduced +by removing a single point. The value of this option is a distance, +specified in miles by default. You may also specify the distance in +kilometers by adding a 'k' to the end of the number. +

+How the error is determined depends on whether the length +or crosstrack method is used. If you are using the length +method, the error is the change in the length of the route introduced by +removing a point. If you are using the crosstrack method, the error is the +distance from the point to the line that results if that point is removed. +

crosstrack option

+ Use cross-track error (default). +

+This option instructs GPSBabel to remove points that have the smallest +overall effect on the overall shape of the route. Using this method, the +first point to be removed will be the one that is closest to a line drawn +between the two points adjacent to it. +

+If neither this option nor the length option is specified, +this is the default. +

length option

+ Use arclength error. +

+This option instructs GPSBabel to simplify by removing points that cause the +smallest change in the overall length of the route first. +

Transformate waypoints into a route, tracks into routes, ... (transform)

+ This filter can be used to convert GPS data between different data types. +

+ Some GPS data formats support only some subset of waypoints, tracks, + and routes. The transform filter allows you to convert between these + types. For example, it can be used to convert a pile of waypoints (such + as those from a CSV file) into a track or vice versa. +

+ The following example show you how to create a route from a waypoint table. +

gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx

+ Only the first letter of option value decides which transformation will be done. + Depending on the used option it can be only 'W' for waypoints, 'R' for routes or + 'T' for tracks. +

wpt option

+ Transform track(s) or route(s) into waypoint(s) [R/T]. +

rte option

+ Transform waypoint(s) or track(s) into route(s) [W/T]. +

trk option

+ Transform waypoint(s) or route(s) into tracks(s) [W/R]. +

del option

+ Delete source data after transformation. +

Appendix A. Supported Datums

+Some formats in GPSBabel support multiple datums. For example, the +datum option to the +garmin_txt format allows you to specify +a datum for the output file. +

+The following is a list of the datums supported by GPSBabel. +

AdindanCarribean NAD27Hjorsey 1955NahrwanSanto (DOS)
AFGCarthageHong Kong 1963Naparima BWISapper Hill 43
Ain-El-AbdCent America NAD27Hu-Tzu-ShanNorth America 83Schwarzeck
Alaska-NAD27Chatham 1971IndianN. America 1927 meanSicily
Alaska-CanadaChua AstroIranObservatorio 1966Sierra Leone 1960
Anna-1-AstroCorrego AlegreIreland 1965Old EgyptianS. Am. 1969 mean
ARC 1950 MeanCuba NAD27ISTS 073 Astro 69Old Hawaiian_meanSouth Asia
ARC 1960 MeanCyprusJohnston Island 61Old Hawaiian KauaiSoutheast Base
Asc Island 58Djakarta(Batavia)KandawalaOld Hawaiian MauiSouthwest Base
Astro B4DOS 1968Kerguelen IslandOld Hawaiian OahuTananarive Obs 25
Astro Beacon EEaster lsland 1967Kertau 48OmanThai/Viet (Indian)
Astro pos 71/4EgyptL.C. 5 AstroOSGB36Timbalai 1948
Astro stn 52European 1950La ReunionPico De Las NievesTokyo mean
Australia Geo 1984European 1950 meanLiberia 1964Pitcairn Astro 67Tristan Astro 1968
Bahamas NAD27European 1979 meanLuzonS. Am. 1956 mean(P)United Arab Emirates
Bellevue IGNFinnish NauticalMahe 1971S. Chilean 1963 (P)Viti Levu 1916
Bermuda 1957Gandajika BaseMarco AstroPuerto RicoWake Eniwetok 60
Bukit RimpahGeodetic Datum 49Masirah Is. NahrwanPulkovo 1942WGS 72
Camp_Area_AstroGhanaMassawaQornoqWGS 84
Campo_InchauspeGreenland NAD27MerchichQuatar NationalYacare
Canada_Mean(NAD27)Guam 1963Mexico NAD27Rome 1940Zanderij
Canal_Zone_(NAD27)Gunung SegaraMidway Astro 61S-42(Pulkovo1942)Sweden
Canton_Island_1966Gunung Serindung 1962MindanaoS.E.Asia_(Indian) 
CapeGUX1 AstroMinnaSAD-69/Brazil 
Cape_Canaveral_meanHerat NorthMontjong LoweSanta Braz 

Appendix B. Garmin Icons

+Following is a list of the valid values for the +garmin deficon option. +These values are also used internally by the +GDB, +BCR, +Mapsource, +Geoniche, +GPilotS, +PCX, and +PSITrex +formats. +

AirportContact, Big EarsGhost TownNavaid, AmberReef
Amusement ParkContact, BikerGlider AreaNavaid, BlackResidence
Anchor ProhibitedContact, BugGolf CourseNavaid, BlueRestaurant
Asian FoodContact, CatGreen circleNavaid, GreenRestricted Area
Ball ParkContact, DogGreen DiamondNavaid, Green/RedRestroom
BankContact, DreadlocksGreen Letter ANavaid, Green/WhiteRV Park
BarContact, Female1Green Letter BNavaid, OrangeScales
BeachContact, Female2Green Letter CNavaid, RedScenic Area
BeaconContact, Female3Green Letter DNavaid, Red/GreenSchool
BellContact, GoateeGreen Number 0Navaid, Red/WhiteSeafood
Bike TrailContact, Kung-FuGreen Number 1Navaid, VioletSeaplane Base
Blue CircleContact, PigGreen Number 2Navaid, WhiteShipwreck
Blue DiamondContact, PirateGreen Number 3Navaid, White/GreenShopping Center
Blue Letter AContact, RangerGreen Number 4Navaid, White/RedShort Tower
Blue Letter BContact, SmileyGreen Number 5Non-directional beaconShower
Blue Letter CContact, SpikeGreen Number 6NullSki Resort
Blue Letter DContact, SumoGreen Number 7Oil FieldSkiing Area
Blue Number 0Controlled AreaGreen Number 8Open 24 HoursSkull and Crossbones
Blue Number 1Convenience StoreGreen Number 9Parachute AreaSmall City
Blue Number 2CrossingGreen OvalParkSoft Field
Blue Number 3DamGreen RectangleParking AreaStadium
Blue Number 4Danger AreaGreen SquarePharmacyState Hwy
Blue Number 5DeliGreen TrianglePicnic AreaSteak
Blue Number 6Department StoreHeliportPin, BlueStreet Intersection
Blue Number 7Diamond, BlueHornPin, GreenSummit
Blue Number 8Diamond, GreenHotelPin, RedSwimming Area
Blue Number 9Diamond, RedHousePizzaTACAN
Blue OvalDiver Down Flag 1Hunting AreaPolice StationTall Tower
Blue RectangleDiver Down Flag 2Ice SkatingPost OfficeTelephone
Blue SquareDockInformationPost OfficeTide/Current PRediction Station
Blue TriangleDrinking WaterIntersectionPrivate FieldToll Booth
Boat RampDropoffIntl freeway hwyRadio BeaconTracBack Point
Border Crossing (Port Of Entry)Elevation pointIntl national hwyRamp intersectionTrail Head
Bottom ConditionsEvent CacheItalian foodRed circleTruck Stop
BowlingExitLarge exit without servicesRed DiamondTunnel
BridgeExit without servicesLarge Ramp intersectionRed Letter AU Marina
BuildingFast FoodLeveeRed Letter BU stump
CampgroundFirst approach fixLightRed Letter CUltralight Area
CarFishing AreaLive TheaterRed Letter DUnknown Cache
Car RentalFishing Hot Spot FacilityLocalizer Outer MarkerRed Number 0US hwy
Car RepairFitness CenterLocationless (Reverse) CacheRed Number 1VHF Omni-range
CemeteryFlagLodgingRed Number 2Virtual cache
ChurchFlag, BlueMan OverboardRed Number 3VOR-DME
Circle with XFlag, GreenMarinaRed Number 4VOR/TACAN
City (Capitol)Flag, RedMedical FacilityRed Number 5Water Hydrant
City (Large)ForestMicro-CacheRed Number 6Waypoint
City (Medium)Gambling/casinoMile MarkerRed Number 7Webcam Cache
City (Small)Gas StationMilitaryRed Number 8Weed Bed
CivilGeocacheMineRed Number 9White Buoy
Coast GuardGeocache FoundMissed approach pointRed OvalWhite Dot
Contact, AfroGeographic place name, landMovie TheaterRed RectangleWrecker
Contact, AlienGeographic place name, Man-madeMulti-CacheRed SquareZoo
Contact, Ball CapGeographic place name, waterMuseumRed Triangle 

Appendix C. GPSBabel XCSV Style Files

Introduction

+Often it is desirable to add a new file format for "one-off" work (perhaps +you want to export something to a spreadsheet or graphing program) or to read +a format that GPSBabel does not yet support. For suitably simple formats, +this can be done by a user with no programming experience by providing a +GPSBabel style file. +

+For a format to be described by a style file, it must be predictable and +generally readable by humant. Formats with binary or unreadable content +are not good fits for this scheme. It should have: +

A fixed header at the beginning, if it has any at all. This is called a 'prologue'.
Waypoints that are grouped by fixed separators, often a newline. In style file parlance, this is called a 'record'.
Traits of that waypoint described in that record. In the style files, these are called 'fields' and examples may include longitude or a name.
Fields that are grouped by fixed separators, often a comma or a tab. In the style files, this is called the field separator.
A fixed footer at the end, if it has any at all. This is called the 'epilogue'.

+

+Once you have created a style file that describes the file format you have +or want, you must tell GPSBabel to use the xcsv format and have the xcsv +format use that file. If you created a new style file called +"mystyle.style" and you want to write the waypoints from +a GPX file named "mine.gpx" to it, you would issue a command like: +

gpsbabel -i gpx -f mine.gpx -o xcsv,style=mystyle.style -f mine.new

+You might then examine mine.new to see if it met +your expectations. If not, you could continue to tweak +mystyle.style until it did, rerunning the above +command each time. If 'mystyle' is a format +that describes a popular program or is likely to be of use to others, you can +then share mystyle.style with other GPSBabel users. +Send it along with a coherent descripton to the GPSBabel-misc mailing +list for consideration to be included in a future version. +

Style file overview

+The first and foremost important step is understanding how the style +file is laid out itself. The format is: +

DIRECTIVE<whitespace>VALUE

+Where <whitespace> is one or more spaces or tabs. There should +be no spaces or tabs at the beginning of the line; all directives start +at the left edge in column zero. +

+An example style format is shown here: +


+
+# Format: MS S&T 2002/2003
+# Author: Alex Mottram
+#   Date: 12/09/2002
+#
+
+DESCRIPTION  Microsoft Streets and Trips 2002-2006
+EXTENSION               txt
+
+#
+# FILE LAYOUT DEFINITIIONS:
+#
+FIELD_DELIMITER TAB
+RECORD_DELIMITER NEWLINE
+BADCHARS ,"
+
+PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr
+
+#
+# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
+# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN
+#       HAVE OUR WAY WITH THE FORMATTING. 
+#
+IFIELD SHORTNAME, "", "%s" # Name
+IFIELD LAT_DECIMAL, "", "%f" # Latitude
+IFIELD LON_DECIMAL, "", "%f" # Longitude
+IFIELD DESCRIPTION, "", "%s" # Name 2 (Big Description)
+IFIELD URL, "", "%s" # URL
+IFIELD GEOCACHE_TYPE, "", "%s" # Geocache Type
+IFIELD GEOCACHE_CONTAINER, "", "%s" # Geocache Type
+IFIELD GEOCACHE_DIFF, "", "%3.1f" # Geocache Type
+IFIELD GEOCACHE_TERR, "", "%3.1f" # Geocache Type
+

+Each of these lines will be explained in the following sections. +

Internal Constants

+A few internal constants are defined in the XCSV parser to make the style +file simpler. They may or may not be used and are optional in most cases. +Note that only certain style file directives map these constants. +

+

Style ConstantMaps to Char(s)
COMMA,
COMMASPACE,<space>
SINGLEQUOTE'
DOUBLEQUOTE"
COLON:
SEMICOLON;
NEWLINE\n
CR\r
CRNEWLINE\r\n
TAB\t
SPACE<space>
HASH#
PIPE|
WHITESPACEsee below

+

WHITESPACE

+The WHITESPACE constant has special properties. When reading data, +WHITESPACE refers to sequential runs of SPACES and/or TABS. When +writing data, WHITESPACE is always a single SPACE. +

+For example, the following line: +

SOME_NAME       30.1208 -91.1365    SOME OTHER NAME
+

+Parses into the following data fields: +

SOME_NAME,30.1208,-91.1365,SOME,OTHER,NAME
+

COMMENTS

+Anything after a hash (#) on a line is not parsed. For example: +

#THIS ENTIRE LINE IS A COMMENT.
+#FIELD	LAT_DECIMAL, "", "%f"   THIS ENTIRE LINE IS A COMMENT
+FIELD LAT_DECIMAL, "", "%f"  # ONLY THIS SENTENCE IS A COMMENT.
+

Global Properties of the File

+There are a few available directives to describe general traits of the +file being described and not specific data within the file itself. +

DESCRIPTION

+This is the description of the file format being described. This text +appears in the help screens and in menus used by the various GUI wrappers. +

EXTENSION

+This directive gives the filename extension generally associated with +this file. +

ENCODING

+Describes the character set used by this format. The value given +must be one listed by 'gpsbabel -l'. example: +

   ENCODING             UTF-8	# Use UTF-8 for input and output.
+

GPSBabel Behavior Directives

+There are a few available directives to control some of the internal +processing functions of GPSbabel. +

SHORTLEN

+ This sets the maximum allowed shortname length when using the internal + shortname synthesizer. +

+ example: +

   SHORTLEN	16	# shortnames will be at most 16 characters long.
+

SHORTWHITE

+ This tells the shortname synthesizer whether or not to allow whitespace + in the synthesized shortnames. Allowed values are zero and one. +

+ example: +

   SHORTWHITE	0	# Do not allow whitespace in shortname.
+   SHORTWHITE   1	# Allow whitespace in shortname.
+

Defining the Layout of the File

+The first few directives define the layout the physical file itself: +

FIELD_DELIMITER

+ The field delimiter defines the character(s) that separate the fields in + the rows of data inside the XCSV file. Common field delimiters are commas + and tabs. (referred to as "comma separated values" and "tab separated + values") +

+ examples: +

   FIELD_DELIMITER    COMMA
+   FIELD_DELIMITER    ~
+

+ The directive FIELD_DELIMITER is parsed for STYLE CONSTANTS as defined in + the table above. +

RECORD_DELIMITER

+ The record delimiter defines that character(s) that separate ROWS of + data (FIELDS) in the XCSV file. The most common record delimiters + are NEWLINE and CR (carriage return). +

+ examples: +

   RECORD_DELIMITER    NEWLINE
+   RECORD_DELIMITER    |
+

+ The directive RECORD_DELIMITER is parsed for STYLE CONSTANTS as defined + in the table above. +

BADCHARS

+ Bad characters are things that should *never* be written into the XCSV + file as data on output. GPSBabel automatically includes any non-blank + FIELD_DELIMITER and RECORD_DELIMITER characters as BADCHARS by default. +

+ examples: +

  BADCHARS    COMMA
+  BADCHARS    ~|
+

+ The directive BADCHARS is parsed for STYLE CONSTANTS as defined in the + table above. +

PROLOGUE

+ A prologue is basically constant data that is written to the output + file BEFORE any waypoints are processed. PROLOGUE can be defined + multiple times in the style file, once for each "line" before the data + begins. This is commonly used in XCSV files as a "header" row. +

+ examples: +

  PROLOGUE	OziExplorer Waypoint File Version 1.1
+  PROLOGUE	WGS 84
+  PROLOGUE	Symbol,Name,Latitude,Longitude
+

EPILOGUE

+ An Epilogue is the same as a prologue, except this data is written at + the END of the file. See the examples for PROLOGUE above. +

Defining Fields Within the File

+A field defines data. There are two different classifications of FIELDS, +IFIELD (file input) and OFIELD (file output). In the absence of any OFIELDS, +IFIELDS are use as both input and output. The existence of OFIELDS is +primarily to allow more flexible mapping of GPSBabel data to output data +(say, for instance, to map the internal GPSBabel "description" variable to +two or more fields on output). For all practical purposes, IFIELDS and +OFIELDS are defined the same way in the style file.

The following per-field options are defined: +

  • + "no_delim_before" is supported on in OFIELD tags to specify that this + field should be written without a field delimiter before it. It's + useful for limited field concatenation. +

  • + "absolute" is supported on OFIELD tags for lat and lon to indicate + that only absolute values (never negative) are to be printed. +

  • + "optional" is supported only OFIELD tags and indicates that the + field may or may not be available in the source data. If the + field is absent, no trailing field separator is written. +

    + This attribute is most useful when paired with "no_delim_before" as + it allows you to concatenate fields without concern for whether those + fields are actually populated or not. +

+There are several different types of fields that may be defined. Each field +consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and +a PRINTF CONVERSION (for output). In many cases, not all pieces are used, +but all 3 pieces are required. Additionally, an fourth field is supported +that modifies the behaviour of the field being described. +

+FIELDS should be defined in the style file in the logical order that they +appear in the data, from left to right. This is the order in which they are +parsed from input and written to output. +

+The fields used by the XCSV parser are as follows: +

IGNORE

+ IGNORE fields are, guess what, ignored on input. Internally, IGNORE + fields are treated as CHARACTER data, and as such, require a printf + conversion for a character array. +

+examples: +

   IFIELD IGNORE,"","%14.14s"   # (writes a 14 character blank field)
+   IFIELD IGNORE,"","%s"        # (writes a blank field on output)
+

CONSTANT

+ CONSTANT fields are, of course, constant. They are ignored on input, + however they write CONSTANT data on output. As such, they require a + DEFAULT VALUE and a printf conversion for a character array. +

+examples: +

   IFIELD CONSTANT,"FFFFFF","%s"   # (writes "FFFFFF" in the field)
+   IFIELD CONSTANT,"01/01/70","%s" # (a constant date field)
+

INDEX

+ An INDEX field is used ONLY on output. The INDEX constant defines a field + that, at output, contains the sequence number of the waypoint being + written, starting at 0. An index is managed internally as an INTEGER + and requires an INTEGER printf conversion. An INDEX has one special + property. The DEFAULT VALUE of the index is added to the index + on each iteration (to allow indexes starting at 1, 100, etc..). +

+examples: +

   IFIELD INDEX,"0","%04d"     # (Starts counting at zero)
+   IFIELD INDEX,"","%04d"      # (Starts counting at zero)
+   IFIELD INDEX,"1","%04d"     # (Starts counting at one)
+

SHORTNAME

+ A SHORTNAME is generally the waypoint name of the data being processed. + SHORTNAME maps directly to the GPSBabel variable ->shortname. A SHORTNAME + is CHARACTER data and requires a character array printf conversion. +

+example: +

   IFIELD SHORTNAME,"","%s"   # (write shortname in the output file)
+

DESCRIPTION

+ A DESCRIPTION is generally a long description of the waypoint. A + DESCRIPTION maps to the GPSBabel variable ->description and is otherwise + handled exactly like a SHORTNAME. +

+examples: +

   IFIELD DESCRIPTION,"","%s" # (write description in the output file)
+

NOTES

+ NOTES are generally everything else about a waypoints. NOTES map to the + GPSBabel variable ->notes and is otherwise handled exactly like a + SHORTNAME. +

URL

+ URL is a URL for the waypoint. URL maps to the GPSBabel variable + ->url and is otherwise handled exactly like a SHORTNAME. +

+example: +

   IFIELD URL,"","%s" #	(writes the URL in the output file)
+

URL_LINK_TEXT

+ URL_LINK_TEXT is a textual description of where a URL points. + URL_LINK_TEXT maps to the GPSBabel variable ->url_link_text and + is otherwise handled exactly like a SHORTNAME. +

+example: +

   IFIELD URL_LINK_TEXT,"","%s" # (writes link text in the output file)
+

ICON_DESCR

+ ICON_DESCR is a textual description of an icon type for a waypoint. + ICON_DESCR maps to the GPSBabel variable ->icon_desc and is otherwise + handled exactly like a SHORTNAME. +

+example: +

   IFIELD ICON_DESCR,"","%s" # (writes link text in the output file)
+

LAT_DECIMAL

+ LAT_DECIMAL defines LATITUDE in DECIMAL format. Note that this is a PURE + signed decimal format (i.e. -91.0000). This data is handled internally as + a DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf conversion. +

+example: +

   IFIELD LAT_DECIMAL,"","%f"
+

LON_DECIMAL

+ See LAT_DECIMAL, except LON_DECIMAL defines LONGITUDE. +

LAT_INT32DEG

+ LAT_INT32DEG defines LATITUDE in what I call INT32DEGREES. This value is + a signed LONG INTEGER and requires a LONG INTEGER printf conversion. + (This format is only used by some DeLorme products.) +

+example: +

   IFIELD LAT_INT32DEG,"","%ld"
+

LON_INT32DEG

+ See LON_INT32DEG except LON_INT32DEG defines LONGITUDE. +

LAT_DECIMALDIR / LAT_DIRDECIMAL

+ LAT_DECIMALDIR and LAT_DIRDECIMAL define LATITUDE in DECIMAL format + with the added bonus of a 'N/S' or 'E/W' direction character. This data + is handled internally as a DOUBLE PRECISION FLOAT and a single + CHARACTER and requires a FLOATING POINT as well as a CHARACTER printf + conversion. The only difference between the two is whether the directional + character appears before (LAT_DIRDECIMAL) or after (LAT_DECIMALDIR) the + decimal number. +

+examples: +

   IFIELD LAT_DECIMALDIR,"","%f %c"     #  (writes 31.333 N)
+   IFIELD LAT_DIRDECIMAL,"","%c %f"     #  (writes N 31.333)
+

LON_DECIMALDIR / LON_DIRDECIMAL

+ Same as LAT_DECIMALDIR / LAT_DIRDECIMAL except LON_ defines LONGITUDE. +

LAT_DIR / LON_DIR

+ LAT_DIR returns the single character 'N' or 'S' depending on the + hemisphere of the latitude. LON_DIR returns 'E' or 'W' depending on + the hemisphere of the longitude. +

LAT_HUMAN_READABLE

+ LAT_HUMAN_READABLE defines LATITUDE in a human-readable format. This + format is probably the most expressive format. It is similar to + LAT_DECIMALDIR in that it requires multiple printf conversions, but it + is far more flexible as to the contents of those conversions. On read, + the printf conversions are ignored and GPSBabel attempts to determine the + latitude and longitude based on what is in the file. +

+examples: +

   IFIELD LAT_HUMAN_READABLE,"","%c %d %f"   # (writes N 31 40.000)
+   IFIELD LAT_HUMAN_READABLE,"","%d deg %f min %c"
+                              #  (writes "31 deg 40.000 min N")
+          #  Note that this string will confuse the reading routine due 
+          #  to the letter "n" in "min" and the letter "e" in "deg."
+   IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" # (writes 31 40 00.000N)
+

LON_HUMAN_READABLE

+ See LAT_HUMAN_READABLE except LON_HUMAN_READABLE defines LONGITUDE. +

LATLON_HUMAN_READABLE

+ LATLON_HUMAN_READABLE is like LAT_HUMAN_READABLE and LON_HUMAN_READABLE + except that it reads and writes both latitude and longitude as a single + field. On write, the same format specifier is used for both coordinates. + On read, GPSBabel does exactly the same thing it does for + LAT_HUMAN_READABLE or LON_HUMAN_READABLE. +

+example: +

   IFIELD LATLON_HUMAN_READABLE,"","%c %d %f"
+           # (writes "N 31 40.126 W 85 09.62" as a single field)
+

LAT_NMEA

+ Defines the latitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. +

+example: +

   IFIELD  LAT_NMEA, "%f", "%08.3f"     # (writes  3558.322)
+

LON_NMEA

+ Defines the longitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. +

+example: +

   IFIELD  LON_NMEA, "%f", "%010.3f"  # (writes -08708.082)
+

ALT_FEET

+ ALT_FEET is the position's ALTITUDE in FEET. This value is treated as + a SIGNED DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf + conversion. +

+example: +

   IFIELD ALT_FEET,"","%.0f"
+

ALT_METERS

+ ALT_METERS is identical to ALT_FEET with the exception that the altitude + is in METERS. +

HEART_RATE

+ Heart rate, measured in beats per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Forerunner 301). +

+example: +

   IFIELD HEART_RATE,"","%d"
+

CADENCE

+ Cadence in revolutions per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Edge 305). +

+example: +

   IFIELD CADENCE,"","%d"
+

EXCEL_TIME

+ EXCEL_TIME is the waypoint's creation time, if any. This is actually + the decimal days since 1/1/1900 and is handled internally as a DOUBLE + PRECISION FLOAT and requires a FLOATING POINT printf conversion. +

+example: +

   IFIELD EXCEL_TIME,"","%11.5f"
+

TIMET_TIME

+ TIMET_TIME is the waypoint's creation time, if any. This is actually + the integer seconds since 1/1/1970 (let's not start the holy war) and + is handled internally as a LONG INTEGER and requires a LONG INTEGER + printf conversion. +

+example: +

   IFIELD TIMET_TIME,"","%ld"
+

YYYYMMDD_TIME

+ YYYYMMDD_TIME is the waypoint's creation time, if any. It's a single + decimal field containing four digits of year, two digits of month, + and two digits of date. Internally it is a LONG INTEGER and thus + requires a LONG INTEGER printf conversion. +

+example: +

   IFIELD YYYYMMDD_TIME,"","%ld"
+

GMT_TIME

+ GMT_TIME is the waypoint's creation time, in UTC time zone. It uses the + strptime conversion format tags. +

+example: +

   IFIELD GMT_TIME,"","%m/%d/%Y %I:%M:%D %p"
+

+ Search the web for 'strptime man page' for details strptime, but one + such page can be found at +http://www.die.net/doc/linux/man/man3/strptime.3.html +

LOCAL_TIME

+ LOCAL_TIME is the waypoint's creation time, in the local + time zone. It uses strptime conversion format tags. See GMT_TIME for a + reference. +

+example: +

   IFIELD LOCAL_TIME,"","%y-%m-%d"
+

HMSG_TIME

+ HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in UTC. +

+example: +

   IFIELD HMSG_TIME,"","%d:%d:%d %s"
+

HMSL_TIME

+ HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in local time. +

+example: +

   IFIELD HMSL_TIME,"","%dh%dm"
+

ISO_TIME

+ ISO_TIME is the waypoint's creation time, in ISO 8601 format, + which include time zone information. + It is expected to be in the format yyyy-mm-ddThh:mm:sszzzzz + where zzzzzz is the local time offset or the character Z + for UTC time. + On output, UTC 'Z' time zone will always be used. +

+example: +

   IFIELD ISO_TIME,"","%s"
+

GEOCACHE_DIFF

+ GEOCACHE_DIFF is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "difficulty" rating as defined by + Groundspeak. A "three and a half star" cache would therefore be "3.5" +

+example: +

   IFIELD GEOCACHE_DIFF,"","%3.1f"
+

GEOCACHE_TERR

+ GEOCACHE_TERR is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "terrain" rating as defined + by Groundspeak. A "three and a half star" cache would therefore be "3.5" +

+example: +

   IFIELD GEOCACHE_TERR,"","%3.1f"
+

GEOCACHE_CONTAINER

+ GEOCACHE_CONTAINER is valid only for geocaches and is heavily influenced + by the Groundspeak container types. Examples would include "Micro" + and "Virtual". +

+example: +

   GEOCACHE_CONTAINER,"","%s"
+

GEOCACHE_TYPE

+ GEOCACHE_TYPE is valid only for geocaches and is heavily influenced + by the Groundspeak cache types. Examples would include "Event cache" + and "Multi-Cache". +

+example: +

   GEOCACHE_TYPE,"","%s"
+

GEOCACHE_PLACER

+ GEOCACHE_PLACER is a string containing the name of the placer of a + geocache. +

+example: +

   GEOCACHE_PLACER,"","%s"
+

GEOCACHE_LAST_FOUND

+ A long integer in format YYYYMMDD containing the last time this geocache + was found. +

+example: +

   GEOCACHE_LAST_FOUND,"","%ld"
+

GEOCACHE_HINT

+ The hint for this geocache. No additional transformation (such as rot13) + will be performed on this string. +

+example: +

   GEOCACHE_HINT,"","%s"
+

PATH_DISTANCE_MILES

+ PATH_DISTANCE_MILES outputs the total length of the route or track from + the start point to the current point, in miles. This and the altitude + could be used to create an elevation profile. PATH_DISTANCE_MILES is + a DOUBLE PRECISION FLOAT. +

+ PATH_DISTANCE_MILES is not valid as an input field. +

+ PATH_DISTANCE_MILES is only meaningful if the data comes from a track + or a route; waypoint data will generate essentially meaningless output. +

+example: +

   PATH_DISTANCE_MILES,"","%f"
+

PATH_DISTANCE_KM

+ PATH_DISTANCE_KM is like PATH_DISTANCE_MILES except it outputs the + length in kilometers. +

PATH_SPEED

+ Speed in meters per second. Gpsbabel does NOT calculate this data by + default; it is read from the input file if present. (If not present, + it may be calculated with the track + filter.) +

+example: +

   PATH_SPEED,"","%f"
+

PATH_COURSE

+ Course in degerees. Gpsbabel does not calculate this data by default; + it is read from the input file if present. (If not present, it may be + calculated with the track filter.) +

+example: +

   PATH_COURSE,"","%f"
+

GPS_HDOP / GPS_VDOP / GPS_PDOP

+ GPS horizontal / vertical / positional dilution of precision + parameters. Needs float conversion. +

+example: +

   GPS_HDOP,"","%f"
+

GPS_SAT

+ Number of satellites used for determination of the position. Needs + integer conversion. +

+example: +

   GPS_SAT,"","%d"
+

GPS_FIX

+ Type of fix (see GPX spec or track +filter). Needs string conversion. +

+example: +

   GPS_FIX,"","%s"
+

Examples

+Here is one example style file from the GPSBabel source. +


+# gpsbabel XCSV style file
+#
+# Format: Garmin POI
+# Author: Robert Lipe
+# Date: 10/07/2005
+# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204
+#
+DESCRIPTION Garmin POI database
+#
+#
+# FILE LAYOUT DEFINITIIONS:
+#
+FIELD_DELIMITER COMMA
+RECORD_DELIMITER NEWLINE
+BADCHARS COMMA
+SHORTLEN 24
+
+#
+# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
+#
+IFIELD LON_HUMAN_READABLE, "", "%08.5f"
+IFIELD LAT_HUMAN_READABLE, "", "%08.5f"
+IFIELD SHORTNAME, "", "%s"
+IFIELD DESCRIPTION, "", "%s"
+
+OFIELD LON_DECIMAL, "", "%08.5f"
+OFIELD LAT_DECIMAL, "", "%08.5f"
+OFIELD SHORTNAME, "", "%-.24s"
+OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional"
+OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional"
+OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional"
+OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional"
+OFIELD DESCRIPTION, "", "%-.50s"
+

+When used on a Groundspeak Pocket Query, it will output lines that +look like: +


+-76.76234,38.39123,GC5370 Loca/Virt (1.0/1.0),Dude.. Wheres my Limo??
+-90.42345,38.55234,GCC8B Trad/Regu (2.0/2.0),Sweet Reward
+-90.81456,38.62456,GC3091 Trad/Regu (1.5/2.0),Matson Hill
+

+that are suitable for Garmin's POI loader. +

+For additional examples, please see the +*.style files in the +style/ subdirectory of GPSBabel or at the online source tree. +

Miscellaneous Notes

Default Values

+Default values are supported for any output fields that contain pure + character data output such as URL and NOTES. Default values are only + written on output and are not used to supplement missing input. When + using default values your mileage will vary greatly depending on the + input formats used to populate waypoint data. +

diff --git a/gpspilot.c b/gpspilot.c index 712b0e392..704f72e8a 100644 --- a/gpspilot.c +++ b/gpspilot.c @@ -20,6 +20,7 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" @@ -48,14 +49,14 @@ struct runways { static FILE *file_in; static FILE *file_out; static const char *out_fname; -struct pdb *opdb; -struct pdb_record *opdb_rec; +static struct pdb *opdb; +static struct pdb_record *opdb_rec; static char *dbname = NULL; static arglist_t gpspilot_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING}, - {0, 0, 0, 0, 0} + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static void @@ -255,5 +256,7 @@ ff_vecs_t gpspilot_vecs = { data_read, data_write, NULL, - gpspilot_args + gpspilot_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/gpssim.c b/gpssim.c new file mode 100644 index 000000000..67cab0dae --- /dev/null +++ b/gpssim.c @@ -0,0 +1,206 @@ +/* + Write points to Franson Technology GpsGate simulator + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#define MYNAME "gpssim" + +static FILE *fout; +static char *wayptspd; +static char *splitfiles_opt; +static int splitfiles; +static char *fnamestr; +static int trk_count; +static int doing_tracks; + +static +arglist_t gpssim_args[] = { + { "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX }, + { "split", &splitfiles_opt, "Split input into separate files", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +/* + * The only thing kind of odd about this format is the "split" + * option. There's some trashing about with the 'splitfiles' toggle + * to ensure that waypoints land in one file and each track and each + * route land in files of their own. + */ + +static void +gpssim_wr_init(const char *fname) +{ + fnamestr = xstrdup(fname); + trk_count = 0; + splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; + + /* If writing to stdout, never split files */ + if (0 == strcmp("-",splitfiles_opt)) { + splitfiles = 0; + } + + if (!splitfiles) { + fout = xfopen(fname, "wb", MYNAME); + } +} + +static void +gpssim_wr_deinit(void) +{ + if (fout) { + fclose(fout); + fout = NULL; + } + + xfree(fnamestr); +} + + +/* + * All these files are written in binary mode, so put CR/NL pairs + * in them explictly in case we're writing from a UNIX-like host. + */ + +static void +gpssim_write_sentence(const char *const s) +{ + fprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); +} + +static void +gpssim_write_spd(double knotsperhour) +{ + char obuf[1024]; + + snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); + gpssim_write_sentence(obuf); +} + +#define mpsec2knots(n) ((n) * 1.9438445 / 0.51444444) + +static void +gpssim_write_pt(const waypoint *wpt) +{ + char obuf[1024]; + double lat, lon; + + if (wpt->speed > 0) { + gpssim_write_spd(mpsec2knots(wpt->speed)); + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + wpt->altitude == unknown_alt ? 0 : wpt->altitude + ); + + if ( wpt->creation_time ) { + char tbuf[20]; + int hms, ymd; + struct tm *tm; + + tm = gmtime(&wpt->creation_time); + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); + strcat(obuf, tbuf); + } + + gpssim_write_sentence(obuf); +} + +static void +gpssim_trk_hdr(const route_head *rh) +{ + if (splitfiles) { + char c[1024]; + char *ofname = xstrdup(fnamestr); + + if (fout) { + fatal(MYNAME ": output file already open.\n"); + } + + snprintf(c, sizeof(c), "%s%04d.gpssim", + doing_tracks ? "-track" : "-route", + trk_count++); + ofname = xstrappend(ofname, c); + fout = xfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + track_recompute(rh, NULL); +} + +static void +gpssim_trk_ftr(const route_head *rh) +{ + if (splitfiles) { + fclose(fout); + fout = NULL; + } +} + +static void +gpssim_write(void) +{ + if (waypt_count()) { + if (splitfiles) { + char *ofname = xstrdup(fnamestr); + ofname = xstrappend(ofname, "-waypoints.gpssim"); + fout = xfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + if (wayptspd && wayptspd[0]) { + gpssim_write_spd(atof(wayptspd)); + } + waypt_disp_all(gpssim_write_pt); + if (splitfiles) { + fclose(fout); + fout = NULL; + } + } + + doing_tracks = 1; + track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + + trk_count = 0; + doing_tracks = 0; + route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); +} + + +ff_vecs_t gpssim_vecs = { + ff_type_file, + { ff_cap_write, ff_cap_write, ff_cap_write }, + NULL, + gpssim_wr_init, + NULL, + gpssim_wr_deinit, + NULL, + gpssim_write, + NULL, + gpssim_args, + CET_CHARSET_ASCII, 0 +}; diff --git a/gpsutil.c b/gpsutil.c index 983f6649b..7f2c9ae89 100644 --- a/gpsutil.c +++ b/gpsutil.c @@ -21,72 +21,89 @@ #include "defs.h" #include "magellan.h" -static FILE *file_in; -static FILE *file_out; -static void *mkshort_handle; +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; #define MYNAME "GPSUTIL" static void rd_init(const char *fname) { - file_in = xfopen(fname, "r", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = xfopen(fname, "w", MYNAME); + file_out = gbfopen(fname, "w", MYNAME); mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - fclose(file_out); - mkshort_del_handle(mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - char ibuf[100]; - char name[9], desc[31]; + char *ibuf; + char desc[31]; double lat,lon; char latdir, londir; int ilat, ilon; long alt; char alttype; - char icon[3] = {0}; + char icon[3]; waypoint *wpt_tmp; + /* * Make sure that all waypoints in single read have same * timestamp. */ time_t now = current_time(); - - - for(;fgets(ibuf, sizeof(ibuf), file_in);) { + icon[0] = 0; + + while ((ibuf = gbfgetstr(file_in))) { + int n, len; + char *sn; /* A sharp in column zero or an blank line is a comment */ - if (ibuf[0] == '#' || ibuf[0] == '\n') continue; - sscanf(ibuf, "%s %le%c %le%c %ld%c %30[^,] %c", - name, &lat, &latdir, &lon, &londir, + ibuf = lrtrim(ibuf); + len = strlen(ibuf); + if ((len == 0) || (*ibuf == '#')) continue; + + if (len > 71) { + int offs = len - 71; + sn = xstrndup(ibuf, offs + 8); + ibuf += (offs + 9); + } + else { + sn = xstrndup(ibuf, 8); + ibuf += 9; + } + + n = sscanf(ibuf, "%lf%c %lf%c %ld%c %30[^,]s %2s", + &lat, &latdir, &lon, &londir, &alt, &alttype, desc, icon); - desc[0] = '\0'; - icon[0] = '\0'; - sscanf(&ibuf[39], "%30c", desc); - sscanf(&ibuf[70], "%2c", icon); + /* Require at least first threee fields, otherwise ignore */ + if (n < 2) { + xfree(sn); + continue; + } + rtrim(sn); rtrim(desc); rtrim(icon); wpt_tmp = waypt_new(); wpt_tmp->altitude = alt; - wpt_tmp->shortname = xstrdup(name); + wpt_tmp->shortname = sn; wpt_tmp->description = xstrdup(desc); wpt_tmp->creation_time = now; @@ -109,14 +126,14 @@ gpsutil_disp(const waypoint *wpt) { double lon,lat; const char *icon_token; - char *tdesc = str_utf8_to_ascii(wpt->description); + char *tdesc = xstrdup(wpt->description); icon_token = mag_find_token_from_descr(wpt->icon_descr); lon = degrees2ddmm(wpt->longitude); lat = degrees2ddmm(wpt->latitude); - fprintf(file_out, "%-8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", + gbfprintf(file_out, "%-8.8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", global_opts.synthesize_shortnames ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, @@ -149,5 +166,7 @@ ff_vecs_t gpsutil_vecs = { wr_deinit, data_read, data_write, - NULL + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpx.c b/gpx.c index f11401bfd..0541478f9 100644 --- a/gpx.c +++ b/gpx.c @@ -21,7 +21,9 @@ #include "defs.h" #include "xmlgeneric.h" -#ifndef NO_EXPAT +#include "cet_util.h" +#include "garmin_fs.h" +#if HAVE_LIBEXPAT #include static XML_Parser psr; #endif @@ -35,17 +37,17 @@ static const char *gpx_version; static char *gpx_wversion; static int gpx_wversion_num; static const char *gpx_creator; -static char *xsi_schema_loc; +static char *xsi_schema_loc = NULL; static char *gpx_email = NULL; static char *gpx_author = NULL; -vmem_t current_tag; +static vmem_t current_tag; static waypoint *wpt_tmp; static int cache_descr_is_html; static FILE *fd; static FILE *ofd; -static void *mkshort_handle; +static short_handle mkshort_handle; static const char *input_string = NULL; static int input_string_len = 0; @@ -57,12 +59,19 @@ static char *suppresswhite = NULL; static char *urlbase = NULL; static route_head *trk_head; static route_head *rte_head; +/* used for bounds calculation on output */ +static bounds all_bounds; +static format_specific_data **fs_ptr; #define MYNAME "GPX" -#define MY_CBUF 4096 +#define MY_CBUF_SZ 4096 #define DEFAULT_XSI_SCHEMA_LOC "http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd" #define DEFAULT_XSI_SCHEMA_LOC_FMT "\"http://www.topografix.com/GPX/%c/%c http://www.topografix.com/GPX/%c/%c/gpx.xsd\"" +#ifndef CREATOR_NAME_URL +# define CREATOR_NAME_URL "GPSBabel - http://www.gpsbabel.org" +#endif + /* * Format used for floating point formats. Put in one place to make it @@ -77,10 +86,15 @@ static route_head *rte_head; typedef enum { tt_unknown = 0, tt_gpx, - tt_author, + + tt_name, /* Optional file-level info */ tt_desc, + tt_author, tt_email, - tt_time, + tt_url, + tt_urlname, + tt_keywords, + tt_wpt, tt_wpt_cmt, tt_wpt_desc, @@ -111,6 +125,16 @@ typedef enum { tt_cache_log_type, tt_cache_log_date, tt_cache_placer, + + tt_garmin_extension, /* don't change this order */ + tt_garmin_waypt_extension, + tt_garmin_proximity, + tt_garmin_temperature, + tt_garmin_depth, + tt_garmin_display_mode, + tt_garmin_categories, + tt_garmin_category, /* don't change this order */ + tt_rte, tt_rte_name, tt_rte_desc, @@ -143,10 +167,86 @@ typedef enum { tt_trk_trkseg_trkpt_speed, } tag_type; +typedef struct { + queue queue; + char *tagdata; +} gpx_global_entry; + +/* + * The file-level information. + */ +static +struct gpx_global { + gpx_global_entry name; + gpx_global_entry desc; + gpx_global_entry author; + gpx_global_entry email; + gpx_global_entry url; + gpx_global_entry urlname; + gpx_global_entry keywords; + /* time and bounds aren't here; they're recomputed. */ +} *gpx_global ; + +static void +gpx_add_to_global(gpx_global_entry *ge, char *cdata) +{ + queue *elem, *tmp; + gpx_global_entry * gep; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + if (0 == strcmp(cdata, gep->tagdata)) + return; + } + + gep = xcalloc(sizeof(*gep), 1); + QUEUE_INIT(&gep->queue); + gep->tagdata = xstrdup(cdata); + ENQUEUE_TAIL(&ge->queue, &gep->queue); +} + +static void +gpx_rm_from_global(gpx_global_entry *ge) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); + xfree(g->tagdata); + xfree(g); + } +} + +static void +gpx_write_gdata(gpx_global_entry *ge, char *tag) +{ + queue *elem, *tmp; + gpx_global_entry * gep; + + if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { + return; + } + + fprintf(ofd, "<%s>", tag); + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + fprintf(ofd, "%s", gep->tagdata); + /* Some tags we just output once. */ + if ((0 == strcmp(tag, "url")) || + (0 == strcmp(tag, "email"))) { + break; + } + fprintf(ofd, " "); + } + fprintf(ofd, "\n", tag); +} + + typedef struct tag_mapping { tag_type tag_type; /* enum from above for this tag */ int tag_passthrough; /* true if we don't generate this */ const char *tag_name; /* xpath-ish tag name */ + unsigned long crc; /* Crc32 of tag_name */ } tag_mapping; /* @@ -156,95 +256,109 @@ typedef struct tag_mapping { */ tag_mapping tag_path_map[] = { - { tt_gpx, 0, "/gpx" }, - { tt_time, 0, "/gpx/time" }, - { tt_author, 0, "/gpx/author" }, - { tt_email, 0, "/gpx/email" }, - { tt_time, 0, "/gpx/time" }, - { tt_desc, 0, "/gpx/desc" }, - - { tt_wpt, 0, "/gpx/wpt" }, - { tt_wpt_ele, 0, "/gpx/wpt/ele" }, - { tt_wpt_time, 0, "/gpx/wpt/time" }, - { tt_wpt_name, 0, "/gpx/wpt/name" }, - { tt_wpt_cmt, 0, "/gpx/wpt/cmt" }, - { tt_wpt_desc, 0, "/gpx/wpt/desc" }, - { tt_wpt_url, 0, "/gpx/wpt/url" }, - { tt_wpt_urlname, 0, "/gpx/wpt/urlname" }, - { tt_wpt_link, 0, "/gpx/wpt/link" }, /* GPX 1.1 */ - { tt_wpt_link_text, 0, "/gpx/wpt/link/text" }, /* GPX 1.1 */ - { tt_wpt_sym, 0, "/gpx/wpt/sym" }, - { tt_wpt_type, 1, "/gpx/wpt/type" }, - { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, - { tt_cache_name, 1, "/gpx/wpt/groundspeak:cache/groundspeak:name" }, - { tt_cache_container, 1, "/gpx/wpt/groundspeak:cache/groundspeak:container" }, - { tt_cache_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:type" }, - { tt_cache_difficulty, 1, "/gpx/wpt/groundspeak:cache/groundspeak:difficulty" }, - { tt_cache_terrain, 1, "/gpx/wpt/groundspeak:cache/groundspeak:terrain" }, - { tt_cache_hint, 1, "/gpx/wpt/groundspeak:cache/groundspeak:encoded_hints" }, - { tt_cache_desc_short, 1, "/gpx/wpt/groundspeak:cache/groundspeak:short_description" }, - { tt_cache_desc_long, 1, "/gpx/wpt/groundspeak:cache/groundspeak:long_description" }, - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt" }, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type" }, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date" }, - { tt_cache_placer, 1, "/gpx/wpt/groundspeak:cache/groundspeak:owner" }, - - { tt_rte, 0, "/gpx/rte" }, - { tt_rte_name, 0, "/gpx/rte/name" }, - { tt_rte_desc, 0, "/gpx/rte/desc" }, - { tt_rte_number, 0, "/gpx/rte/number" }, - { tt_rte_rtept, 0, "/gpx/rte/rtept" }, - { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele" }, - { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time" }, - { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name" }, - { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt" }, - { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc" }, - { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url" }, - { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname" }, - { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym" }, - - { tt_trk, 0, "/gpx/trk" }, - { tt_trk_name, 0, "/gpx/trk/name" }, - { tt_trk_desc, 0, "/gpx/trk/desc" }, - { tt_trk_trkseg, 0, "/gpx/trk/trkseg" }, - { tt_trk_number, 0, "/gpx/trk/number" }, - { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt" }, - { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele" }, - { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time" }, - { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name" }, - { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt" }, - { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc" }, - { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url" }, - { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname" }, - { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym" }, - { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course" }, - { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed" }, + { tt_gpx, 0, "/gpx", 0UL }, + { tt_name, 0, "/gpx/name", 0UL }, + { tt_desc, 0, "/gpx/desc", 0UL }, + { tt_author, 0, "/gpx/author", 0UL }, + { tt_email, 0, "/gpx/email", 0UL }, + { tt_url, 0, "/gpx/url", 0UL }, + { tt_urlname, 0, "/gpx/urlname", 0UL }, + { tt_keywords, 0, "/gpx/keywords", 0UL }, + + { tt_wpt, 0, "/gpx/wpt", 0UL }, + { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, + { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, + { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, + { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, + { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, + { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, + { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, + { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ + { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ + { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, + { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, + + { tt_cache, 1, "/gpx/wpt/groundspeak:cache", 0UL }, + { tt_cache_name, 1, "/gpx/wpt/groundspeak:cache/groundspeak:name", 0UL }, + { tt_cache_container, 1, "/gpx/wpt/groundspeak:cache/groundspeak:container", 0UL }, + { tt_cache_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:type", 0UL }, + { tt_cache_difficulty, 1, "/gpx/wpt/groundspeak:cache/groundspeak:difficulty", 0UL }, + { tt_cache_terrain, 1, "/gpx/wpt/groundspeak:cache/groundspeak:terrain", 0UL }, + { tt_cache_hint, 1, "/gpx/wpt/groundspeak:cache/groundspeak:encoded_hints", 0UL }, + { tt_cache_desc_short, 1, "/gpx/wpt/groundspeak:cache/groundspeak:short_description", 0UL }, + { tt_cache_desc_long, 1, "/gpx/wpt/groundspeak:cache/groundspeak:long_description", 0UL }, + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt", 0UL }, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type", 0UL }, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date", 0UL }, + { tt_cache_placer, 1, "/gpx/wpt/groundspeak:cache/groundspeak:owner", 0UL }, + + { tt_garmin_extension, 0, "/gpx/wpt/extensions", 0UL }, + { tt_garmin_waypt_extension, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension", 0UL }, + { tt_garmin_proximity, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension/gpxx:Proximity", 0UL }, + { tt_garmin_temperature, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension/gpxx:Temperature", 0UL }, + { tt_garmin_depth, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension/gpxx:Depth", 0UL }, + { tt_garmin_display_mode, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension/gpxx:DisplayMode", 0UL }, + { tt_garmin_categories, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension/gpxx:Categories", 0UL }, + { tt_garmin_category, 0, "/gpx/wpt/extensions/gpxx:WaypointExtension/gpxx:Categories/gpxx:Category", 0UL }, + + { tt_rte, 0, "/gpx/rte", 0UL }, + { tt_rte_name, 0, "/gpx/rte/name", 0UL }, + { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, + { tt_rte_number, 0, "/gpx/rte/number", 0UL }, + { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, + { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, + { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, + { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, + { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, + { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, + { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, + { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, + { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, + + { tt_trk, 0, "/gpx/trk", 0UL }, + { tt_trk_name, 0, "/gpx/trk/name", 0UL }, + { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, + { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, + { tt_trk_number, 0, "/gpx/trk/number", 0UL }, + { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, + { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, + { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, + { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, + { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, + { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, + { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, + { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, + { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, + { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, + { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, /* Common to tracks, routes, and waypts */ - { tt_fix, 0, "/gpx/wpt/fix" }, - { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix" }, - { tt_fix, 0, "/gpx/rte/rtept/fix" }, - { tt_sat, 0, "/gpx/wpt/sat" }, - { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat" }, - { tt_sat, 0, "/gpx/rte/rtept/sat" }, - { tt_pdop, 0, "/gpx/wpt/pdop" }, - { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop" }, - { tt_pdop, 0, "/gpx/rte/rtept/pdop" }, - { tt_hdop, 0, "/gpx/wpt/hdop" }, - { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop" }, - { tt_hdop, 0, "/gpx/rte/rtept/hdop" }, - { tt_vdop, 0, "/gpx/wpt/vdop" }, - { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop" }, - { tt_vdop, 0, "/gpx/rte/rtept/hdop" }, - {0} + { tt_fix, 0, "/gpx/wpt/fix", 0UL }, + { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, + { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, + { tt_sat, 0, "/gpx/wpt/sat", 0UL }, + { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, + { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, + { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, + { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + {0, 0, NULL, 0UL} }; static tag_type get_tag(const char *t, int *passthrough) { tag_mapping *tm; + unsigned long tcrc = get_crc32_s(t); + for (tm = tag_path_map; tm->tag_type != 0; tm++) { - if (0 == strcmp(tm->tag_name, t)) { + if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { *passthrough = tm->tag_passthrough; return tm->tag_type; } @@ -253,6 +367,15 @@ get_tag(const char *t, int *passthrough) return tt_unknown; } +static void +prescan_tags(void) +{ + tag_mapping *tm; + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + tm->crc = get_crc32_s(tm->tag_name); + } +} + static void tag_gpx(const char **attrv) { @@ -293,6 +416,7 @@ tag_wpt(const char **attrv) } avp+=2; } + fs_ptr = &wpt_tmp->fs; } static void @@ -315,7 +439,6 @@ tag_gs_cache(const char **attrv) { const char **avp; - cache_descr_is_html = 0; for (avp = &attrv[0]; *avp; avp+=2) { if (strcmp(avp[0], "id") == 0) { wpt_tmp->gc_data.id = atoi(avp[1]); @@ -330,14 +453,14 @@ start_something_else(const char *el, const char **attrv) char **avcp = NULL; int attr_count = 0; xml_tag *new_tag; - fs_xml *fs_gpx = NULL; - - if ( !wpt_tmp ) { + fs_xml *fs_gpx; + + if ( !fs_ptr ) { return; } - new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); - new_tag->tagname = xstrdup(el); + new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); + new_tag->tagname = xstrdup(el); /* count attributes */ while (*avp) { @@ -371,7 +494,7 @@ start_something_else(const char *el, const char **attrv) } } else { - fs_gpx = (fs_xml *)fs_chain_find( wpt_tmp->fs, FS_GPX ); + fs_gpx = (fs_xml *)fs_chain_find( *fs_ptr, FS_GPX ); if ( fs_gpx && fs_gpx->tag ) { cur_tag = fs_gpx->tag; @@ -384,7 +507,7 @@ start_something_else(const char *el, const char **attrv) else { fs_gpx = fs_xml_alloc(FS_GPX); fs_gpx->tag = new_tag; - fs_chain_add( &(wpt_tmp->fs), (format_specific_data *)fs_gpx ); + fs_chain_add( fs_ptr, (format_specific_data *)fs_gpx ); new_tag->parent = NULL; } } @@ -438,11 +561,13 @@ tag_log_wpt(const char **attrv) } static void -gpx_start(void *data, const char *el, const char **attr) +gpx_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { char *e; char *ep; int passthrough; + const char *el = xml_convert_to_char_string(xml_el); + const char **attr = xml_convert_attrs_to_char_string(xml_attr); vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); e = current_tag.mem; @@ -472,6 +597,7 @@ gpx_start(void *data, const char *el, const char **attr) case tt_rte: rte_head = route_head_alloc(); route_add_head(rte_head); + fs_ptr = &rte_head->fs; break; case tt_rte_rtept: tag_wpt(attr); @@ -479,6 +605,7 @@ gpx_start(void *data, const char *el, const char **attr) case tt_trk: trk_head = route_head_alloc(); track_add_head(trk_head); + fs_ptr = &trk_head->fs; break; case tt_trk_trkseg_trkpt: tag_wpt(attr); @@ -503,6 +630,8 @@ gpx_start(void *data, const char *el, const char **attr) if (passthrough) { start_something_else(el, attr); } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } struct @@ -520,6 +649,8 @@ gs_type_mapping{ { gt_cito, "Cache In Trash Out Event" }, { gt_letterbox, "Letterbox Hybrid" }, { gt_locationless, "Locationless (Reverse) Cache" }, + { gt_ape, "Project APE Cache" }, + { gt_mega, "Mega-Event Cache" }, { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ }; @@ -530,6 +661,7 @@ gs_container_mapping{ const char *name; } gs_container_map[] = { { gc_other, "Unknown" }, + { gc_other, "Other" }, /* Synonym on read. */ { gc_micro, "Micro" }, { gc_regular, "Regular" }, { gc_large, "Large" }, @@ -604,6 +736,8 @@ xml_parse_time( const char *cdatastr ) struct tm tm; time_t rv = 0; char *timestr = xstrdup( cdatastr ); + + memset(&tm, 0, sizeof(tm)); offsetstr = strchr( timestr, 'Z' ); if ( offsetstr ) { @@ -648,42 +782,56 @@ xml_parse_time( const char *cdatastr ) rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; - xfree(timestr); + xfree(timestr); return rv; } static void -gpx_end(void *data, const char *el) +gpx_end(void *data, const XML_Char *xml_el) { + const char *el = xml_convert_to_char_string(xml_el); char *s = strrchr(current_tag.mem, '/'); float x; char *cdatastrp = cdatastr.mem; int passthrough; static time_t gc_log_date; + tag_type tag; if (strcmp(s + 1, el)) { fprintf(stderr, "Mismatched tag %s\n", el); } - switch (get_tag(current_tag.mem, &passthrough)) { + tag = get_tag(current_tag.mem, &passthrough); + switch(tag) { /* * First, the tags that are file-global. */ - case tt_time: - file_time = xml_parse_time(cdatastrp); + case tt_name: + gpx_add_to_global(&gpx_global->name, cdatastrp); break; - case tt_email: - if (gpx_email) xfree(gpx_email); - gpx_email = xstrdup(cdatastrp); + case tt_desc: + gpx_add_to_global(&gpx_global->desc, cdatastrp); break; case tt_author: - if (gpx_author) xfree(gpx_author); - gpx_author = xstrdup(cdatastrp); + gpx_add_to_global(&gpx_global->author, cdatastrp); break; - case tt_gpx: - /* Could invoke release code here */ + case tt_email: + gpx_add_to_global(&gpx_global->email, cdatastrp); + if (gpx_email == NULL) { + gpx_email = xstrdup(cdatastrp); + } + break; + case tt_url: + gpx_add_to_global(&gpx_global->url, cdatastrp); break; + case tt_urlname: + gpx_add_to_global(&gpx_global->urlname, cdatastrp); + break; + case tt_keywords: + gpx_add_to_global(&gpx_global->keywords, cdatastrp); + break; + /* * Waypoint-specific tags. */ @@ -701,6 +849,7 @@ gpx_end(void *data, const char *el) wpt_tmp = NULL; break; case tt_cache_name: + if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); wpt_tmp->notes = xstrdup(cdatastrp); break; case tt_cache_container: @@ -755,6 +904,18 @@ gpx_end(void *data, const char *el) } gc_log_date = 0; break; + + /* + * Garmin-waypoint-specific tags. + */ + case tt_garmin_proximity: + case tt_garmin_temperature: + case tt_garmin_depth: + case tt_garmin_display_mode: + case tt_garmin_category: + garmin_fs_xml_convert(tt_garmin_extension, tag, cdatastrp, wpt_tmp); + break; + /* * Route-specific tags. */ @@ -765,6 +926,7 @@ gpx_end(void *data, const char *el) break; case tt_rte_rtept: route_add_wpt(rte_head, wpt_tmp); + wpt_tmp = NULL; break; case tt_rte_desc: rte_head->rte_desc = xstrdup(cdatastrp); @@ -781,7 +943,8 @@ gpx_end(void *data, const char *el) case tt_trk: break; case tt_trk_trkseg_trkpt: - route_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); + wpt_tmp = NULL; break; case tt_trk_desc: trk_head->rte_desc = xstrdup(cdatastrp); @@ -828,6 +991,7 @@ gpx_end(void *data, const char *el) case tt_wpt_desc: case tt_trk_trkseg_trkpt_desc: case tt_rte_rtept_desc: + if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); wpt_tmp->notes = xstrdup(cdatastrp); break; case tt_pdop: @@ -863,31 +1027,40 @@ gpx_end(void *data, const char *el) break; } - if (passthrough) + if (passthrough) { end_something_else(); + } *s = 0; + xml_free_converted_string(el); } -#if NO_EXPAT -void +#if ! HAVE_LIBEXPAT +static void gpx_rd_init(const char *fname) { fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } +static void +gpx_rd_deinit(void) +{ +} + #else /* NO_EXPAT */ static void -gpx_cdata(void *dta, const XML_Char *s, int len) +gpx_cdata(void *dta, const XML_Char *xml_el, int len) { char *estr; int *cdatalen; char **cdata; xml_tag *tmp_tag; + size_t slen = strlen(cdatastr.mem); + const char *s = xml_convert_to_char_string_n(xml_el, &len); - vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); - estr = (char *) cdatastr.mem + strlen(cdatastr.mem); + vmem_realloc(&cdatastr, 1 + len + slen); + estr = ((char *) cdatastr.mem) + slen; memcpy(estr, s, len); estr[len] = 0; @@ -916,9 +1089,11 @@ gpx_cdata(void *dta, const XML_Char *s, int len) memcpy( estr, s, len ); *(estr+len) = '\0'; *cdatalen += len; + + xml_free_converted_string(s); } -void +static void gpx_rd_init(const char *fname) { if ( fname[0] ) { @@ -934,29 +1109,41 @@ gpx_rd_init(const char *fname) file_time = 0; current_tag = vmem_alloc(1, 0); *((char *)current_tag.mem) = '\0'; + + prescan_tags(); psr = XML_ParserCreate(NULL); if (!psr) { fatal(MYNAME ": Cannot create XML Parser\n"); } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + cdatastr = vmem_alloc(1, 0); *((char *)cdatastr.mem) = '\0'; - /* We don't use xstrdup here because we' know we don't free - * this across reads and we unlock the safety belt from the - * leak tester. - */ if (!xsi_schema_loc) { - xsi_schema_loc = strdup(DEFAULT_XSI_SCHEMA_LOC); + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); } if (!xsi_schema_loc) { - fatal("gpx: Unable to allocate %d bytes of memory.\n", strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + fatal("gpx: Unable to allocate %ld bytes of memory.\n", + (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + } + + if (NULL == gpx_global) { + gpx_global = xcalloc(sizeof(*gpx_global), 1); + QUEUE_INIT(&gpx_global->name.queue); + QUEUE_INIT(&gpx_global->desc.queue); + QUEUE_INIT(&gpx_global->author.queue); + QUEUE_INIT(&gpx_global->email.queue); + QUEUE_INIT(&gpx_global->url.queue); + QUEUE_INIT(&gpx_global->urlname.queue); + QUEUE_INIT(&gpx_global->keywords.queue); } XML_SetElementHandler(psr, gpx_start, gpx_end); XML_SetCharacterDataHandler(psr, gpx_cdata); + fs_ptr = NULL; } -#endif static void @@ -969,11 +1156,14 @@ gpx_rd_deinit(void) * this across reads or else merges/copies of files with different * schemas won't retain the headers. * - if ( xsi_schema_loc ) { + * moved to gpx_exit + + if ( xsi_schema_loc ) { xfree(xsi_schema_loc); xsi_schema_loc = NULL; } - */ + */ + if ( gpx_email ) { xfree(gpx_email); gpx_email = NULL; @@ -987,9 +1177,12 @@ gpx_rd_deinit(void) } XML_ParserFree(psr); psr = NULL; + wpt_tmp = NULL; + cur_tag = NULL; } +#endif -void +static void gpx_wr_init(const char *fname) { mkshort_handle = mkshort_new_handle(); @@ -1001,17 +1194,18 @@ static void gpx_wr_deinit(void) { fclose(ofd); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } void gpx_read(void) { -#ifndef NO_EXPAT +#if HAVE_LIBEXPAT int len; int done = 0; - char buf[MY_CBUF]; + char *buf = xmalloc(MY_CBUF_SZ); int result = 0; + int extra; while (!done) { if ( fd ) { @@ -1024,19 +1218,20 @@ gpx_read(void) * them not validate which croaks expat and torments * users. * - * Look for '&' in the last 6 chars. If we find - * it, strip it, then read byte-at-a-time until - * we find a non-entity. + * Look for '&' in the last maxentlength chars. If + * we find it, strip it, then read byte-at-a-time + * until we find a non-entity. */ char *badchar; char *semi; - len = fread(buf, 1, sizeof(buf)-7, fd); + int maxentlength = 8; + len = fread(buf, 1, MY_CBUF_SZ - maxentlength, fd); done = feof(fd) || !len; buf[len] = '\0'; - badchar = buf+len-7; + badchar = buf+len-maxentlength; badchar = strchr( badchar, '&' ); - while ( badchar ) { - int extra = 7; + extra = maxentlength - 1; /* for terminator */ + while ( badchar && len < MY_CBUF_SZ-1) { semi = strchr( badchar, ';'); while ( extra && !semi ) { len += fread( buf+len, 1, 1, fd); @@ -1085,11 +1280,12 @@ gpx_read(void) } if (!result) { fatal(MYNAME ": XML parse error at %d: %s\n", - XML_GetCurrentLineNumber(psr), + (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); } } -#endif /* NO_EXPAT */ + xfree(buf); +#endif /* HAVE_LIBEXPAT */ } static void @@ -1126,12 +1322,12 @@ fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) if ( tag->child ) { fprint_xml_chain(tag->child, wpt); } - if ( strcmp(tag->tagname, "groundspeak:cache" ) == 0 - && wpt->gc_data.exported) { + if ( wpt && wpt->gc_data.exported && + strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { xml_write_time( ofd, wpt->gc_data.exported, "groundspeak:exported" ); } - fprintf( ofd, "", tag->tagname); + fprintf( ofd, "\n", tag->tagname); } if ( tag->parentcdata ) { tmp_ent = xml_entitize(tag->parentcdata); @@ -1158,7 +1354,7 @@ void free_gpx_extras( xml_tag *tag ) xfree(tag->parentcdata); } if (tag->tagname) { - xfree(tag->tagname); + xfree(tag->tagname); } if (tag->attributes) { ap = tag->attributes; @@ -1225,6 +1421,13 @@ gpx_write_common_acc(const waypoint *waypointp, const char *indent) case fix_pps: fix = "pps"; break; + case fix_none: + fix = "none"; + break; + /* GPX spec says omit if we don't know. */ + case fix_unknown: + default: + break; } if (fix) { fprintf(ofd, "%s%s\n", indent, fix); @@ -1274,7 +1477,7 @@ gpx_waypt_pr(const waypoint *waypointp) { const char *oname; char *odesc; - fs_xml *fs_gpx = NULL; + fs_xml *fs_gpx; /* * Desparation time, try very hard to get a good shortname @@ -1303,12 +1506,17 @@ gpx_waypt_pr(const waypoint *waypointp) if ( fs_gpx ) { fprint_xml_chain( fs_gpx->tag, waypointp ); } + if (gpx_wversion_num > 10) { + garmin_fs_xml_fprint(ofd, waypointp); + } fprintf(ofd, "\n"); } static void gpx_track_hdr(const route_head *rte) { + fs_xml *fs_gpx; + fprintf(ofd, "\n"); write_optional_xml_entity(ofd, " ", "name", rte->rte_name); write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); @@ -1316,11 +1524,18 @@ gpx_track_hdr(const route_head *rte) fprintf(ofd, "%d\n", rte->rte_num); } fprintf(ofd, "\n"); + + fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, NULL ); + } } static void gpx_track_disp(const waypoint *waypointp) { + fs_xml *fs_gpx; + fprintf(ofd, "\n", waypointp->latitude, waypointp->longitude); @@ -1347,6 +1562,11 @@ gpx_track_disp(const waypoint *waypointp) NULL : waypointp->shortname); gpx_write_common_acc(waypointp, " "); + fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, waypointp ); + } + fprintf(ofd, "\n"); } @@ -1366,17 +1586,26 @@ void gpx_track_pr() static void gpx_route_hdr(const route_head *rte) { + fs_xml *fs_gpx; + fprintf(ofd, "\n"); write_optional_xml_entity(ofd, " ", "name", rte->rte_name); write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); if (rte->rte_num) { fprintf(ofd, " %d\n", rte->rte_num); } + + fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, NULL ); + } } static void gpx_route_disp(const waypoint *waypointp) { + fs_xml *fs_gpx; + fprintf(ofd, " \n", waypointp->latitude, waypointp->longitude); @@ -1384,6 +1613,12 @@ gpx_route_disp(const waypoint *waypointp) gpx_write_common_position(waypointp, " "); gpx_write_common_description(waypointp, " ", waypointp->shortname); gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); + if ( fs_gpx ) { + fprint_xml_chain( fs_gpx->tag, waypointp ); + } + fprintf(ofd, " \n"); } @@ -1400,12 +1635,34 @@ void gpx_route_pr() route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); } -void +static void +gpx_waypt_bound_calc(const waypoint *waypointp) +{ + waypt_add_to_bounds(&all_bounds, waypointp); +} + +static void +gpx_write_bounds(void) +{ + waypt_init_bounds(&all_bounds); + + waypt_disp_all(gpx_waypt_bound_calc); + route_disp_all(NULL, NULL, gpx_waypt_bound_calc); + track_disp_all(NULL, NULL, gpx_waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + fprintf(ofd, "\n", + all_bounds.min_lat, all_bounds.min_lon, + all_bounds.max_lat, all_bounds.max_lon); + } +} + +static void gpx_write(void) { time_t now = 0; int short_length; - bounds bounds; gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; @@ -1413,12 +1670,9 @@ gpx_write(void) fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); } - now = current_time(); + now = current_time(); - if (snlen) - short_length = atoi(snlen); - else - short_length = 32; + short_length = atoi(snlen); if (suppresswhite) { setshort_whitespace_ok(mkshort_handle, 0); @@ -1426,9 +1680,9 @@ gpx_write(void) setshort_length(mkshort_handle, short_length); - fprintf(ofd, "\n"); + fprintf(ofd, "\n", global_opts.charset_name); fprintf(ofd, " 10) { fprintf(ofd, "\n"); } - xml_write_time( ofd, now, "time" ); - waypt_compute_bounds(&bounds); - if (bounds.max_lat > -360) { - fprintf(ofd, "\n", - bounds.min_lat, bounds.min_lon, - bounds.max_lat, bounds.max_lon); + gpx_write_gdata(&gpx_global->name, "name"); + gpx_write_gdata(&gpx_global->desc, "desc"); + /* In GPX 1.1, author changed from a string to a PersonType. + * since it's optional, we just drop it instead of rewriting it. + */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->author, "author"); } + gpx_write_gdata(&gpx_global->email, "email"); + gpx_write_gdata(&gpx_global->url, "url"); + gpx_write_gdata(&gpx_global->urlname, "urlname"); + xml_write_time( ofd, now, "time" ); + gpx_write_gdata(&gpx_global->keywords, "keywords"); + + gpx_write_bounds(); if (gpx_wversion_num > 10) { fprintf(ofd, "\n"); @@ -1463,21 +1724,49 @@ gpx_write(void) fprintf(ofd, "\n"); } + +static void +gpx_free_gpx_global(void) +{ + gpx_rm_from_global(&gpx_global->name); + gpx_rm_from_global(&gpx_global->desc); + gpx_rm_from_global(&gpx_global->author); + gpx_rm_from_global(&gpx_global->email); + gpx_rm_from_global(&gpx_global->url); + gpx_rm_from_global(&gpx_global->urlname); + gpx_rm_from_global(&gpx_global->keywords); + xfree(gpx_global); +} + +static void +gpx_exit(void) +{ + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + + if (gpx_global) { + gpx_free_gpx_global(); + gpx_global = NULL; + } +} + static arglist_t gpx_args[] = { { "snlen", &snlen, "Length of generated shortnames", - NULL, ARGTYPE_INT }, + "32", ARGTYPE_INT, "1", NULL }, { "suppresswhite", &suppresswhite, - "Suppress whitespace in generated shortnames", - NULL, ARGTYPE_BOOL }, + "No whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, { "logpoint", &opt_logpoint, "Create waypoints from geocache log entries", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, { "urlbase", &urlbase, "Base URL for link tag in output", - NULL, ARGTYPE_STRING}, + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, { "gpxver", &gpx_wversion, "Target GPX version for output", - "1.0", ARGTYPE_STRING}, - { 0, 0, 0, 0, 0 } + "1.0", ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; ff_vecs_t gpx_vecs = { @@ -1489,6 +1778,7 @@ ff_vecs_t gpx_vecs = { gpx_wr_deinit, gpx_read, gpx_write, - NULL, + gpx_exit, gpx_args, + CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ }; diff --git a/grtcirc.c b/grtcirc.c index d5e5cddbb..44ecf1adf 100644 --- a/grtcirc.c +++ b/grtcirc.c @@ -18,8 +18,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ +#include #include #include "defs.h" +#include "grtcirc.h" + +static const double EARTH_RAD = 6378137.0; static void crossproduct( double x1, double y1, double z1, double x2, double y2, double z2, @@ -45,14 +49,71 @@ static double dotproduct( double x1, double y1, double z1, * time, so why not leave the expression human-readable? */ -double tomiles( double rads ) { - const double radmiles = 6378137.0*100.0/2.54/12.0/5280.0; +double radtomiles( double rads ) { + const double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; return (rads*radmiles); } -double gcdist( double lat1, double lon1, double lat2, double lon2 ) { - return acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2)); +double radtometers( double rads ) { + return ( rads * EARTH_RAD ); +} + +double gcdist( double lat1, double lon1, double lat2, double lon2 ) +{ + double res; + double sdlat, sdlon; + + errno = 0; + + sdlat = sin((lat1 - lat2) / 2.0); + sdlon = sin((lon1 - lon2) / 2.0); + + res = sqrt(sdlat * sdlat + cos(lat1) * cos(lat2) * sdlon * sdlon); + + if (res > 1.0) { + res = 1.0; + } else if (res < -1.0) { + res = -1.0; + } + + res = asin(res); + + if ( +#if defined isnan + /* This is a C99-ism. */ + (isnan(res)) || +#endif + (errno == EDOM)) { /* this should never happen: */ + errno = 0; /* Math argument out of domain of + function, */ + return 0; /* or value returned is not a number */ + } + + return 2.0 * res; +} + +/* This value is the heading you'd leave point 1 at to arrive at point 2. + * Inputs and outputs are in radians. + */ +double heading( double lat1, double lon1, double lat2, double lon2 ) { + double v1, v2; + v1 = sin(lon1 - lon2) * cos(lat2); + v2 = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2); + /* rounding error protection */ + if (fabs(v1) < 1e-15) v1 = 0.0; + if (fabs(v2) < 1e-15) v2 = 0.0; + return atan2(v1, v2); +} + +/* As above, but outputs is in degrees from 0 - 359. Inputs are still radians. */ +double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ) +{ + double h = 360.0 - DEG(heading(lat1, lon1, lat2, lon2)); + if (h >= 360.0) h -= 360.0; + + return h; } + double linedist(double lat1, double lon1, double lat2, double lon2, @@ -81,9 +142,9 @@ double linedist(double lat1, double lon1, int newpoints; /* degrees to radians */ - lat1 *= M_PI/180.0; lon1 *= M_PI/180.0; - lat2 *= M_PI/180.0; lon2 *= M_PI/180.0; - lat3 *= M_PI/180.0; lon3 *= M_PI/180.0; + lat1 = RAD(lat1); lon1 = RAD(lon1); + lat2 = RAD(lat2); lon2 = RAD(lon2); + lat3 = RAD(lat3); lon3 = RAD(lon3); newpoints = 1; if ( lat1 == _lat1 && lat2 == _lat2 && lon1 == _lon1 && lon2 == _lon2) { @@ -203,3 +264,85 @@ double linedist(double lat1, double lon1, return 0; } +/* + * Compute the position of a point partially along the geodesic from + * lat1,lon1 to lat2,lon2 + * + * Ref: http://mathworld.wolfram.com/RotationFormula.html + */ + +void linepart(double lat1, double lon1, + double lat2, double lon2, + double frac, + double *reslat, double *reslon ) { + + double x1,y1,z1; + double x2,y2,z2; + double xa,ya,za,la; + double xr, yr, zr; + double xx, yx, zx; + + double theta = 0; + double phi = 0; + double cosphi = 0; + double sinphi = 0; + + /* result must be in degrees */ + *reslat = lat1; + *reslon = lon1; + + /* degrees to radians */ + lat1 = RAD(lat1); lon1 = RAD(lon1); + lat2 = RAD(lat2); lon2 = RAD(lon2); + + /* polar to ECEF rectangular */ + x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + + /* 'a' is the axis; the line that passes through the center of the earth + * and is perpendicular to the great circle through point 1 and point 2 + * It is computed by taking the cross product of the '1' and '2' vectors.*/ + crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + la = sqrt(xa*xa+ya*ya+za*za); + + if ( la ) { + xa /= la; + ya /= la; + za /= la; + } + /* if la is zero, the points are either equal or directly opposite + * each other. Either way, there's no single geodesic, so we punt. */ + if ( la ) { + crossproduct( x1, y1, z1, xa, ya, za, &xx, &yx, &zx ); + + + theta = atan2( dotproduct(xx,yx,zx,x2,y2,z2), + dotproduct(x1,y1,z1,x2,y2,z2)); + + phi = frac * theta; + cosphi = cos(phi); + sinphi = sin(phi); + + + /* The second term of the formula from the mathworld reference is always + * zero, because r (lat1,lon1) is always perpendicular to n (a here) */ + xr = x1*cosphi + xx * sinphi; + yr = y1*cosphi + yx * sinphi; + zr = z1*cosphi + zx * sinphi; + + if ( xr > 1 ) xr = 1; + if ( xr < -1 ) xr = -1; + if ( yr > 1 ) yr = 1; + if ( yr < -1 ) yr = -1; + if ( zr > 1 ) zr = 1; + if ( zr < -1 ) zr = -1; + + *reslat = DEG(asin(yr)); + if( xr == 0 && zr == 0 ) { + *reslon = 0; + } + else { + *reslon = DEG(atan2( zr, xr )); + } + } +} diff --git a/grtcirc.h b/grtcirc.h index de84aea4c..c47e77dd4 100644 --- a/grtcirc.h +++ b/grtcirc.h @@ -18,10 +18,30 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ + +#ifndef GRTCIRC_H +#define GRTCIRC_H + double gcdist( double lat1, double lon1, double lat2, double lon2 ); +double heading( double lat1, double lon1, double lat2, double lon2 ); +double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ); double linedist(double lat1, double lon1, double lat2, double lon2, double lat3, double lon3 ); -double tomiles( double rads ); +double radtometers( double rads ); +double radtomiles( double rads ); + +void linepart(double lat1, double lon1, + double lat2, double lon2, + double frac, + double *reslat, double *reslon ); + +/* Degrees to radians */ +#define DEG(x) ((x)*180.0/M_PI) + +/* Radians to degrees */ +#define RAD(x) ((x)*M_PI/180.0) + +#endif diff --git a/gtm.c b/gtm.c new file mode 100644 index 000000000..379eb29a9 --- /dev/null +++ b/gtm.c @@ -0,0 +1,769 @@ +/* + Support for GPS TrackMaker data file. + + Copyright (C) 2005 Gustavo Niemeyer . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "jeeps/gpsmath.h" + +static FILE *fd, *ofd; +static int indatum; +static int wp_count; +static int ws_count; +static int tr_count; +static int ts_count; +static int rt_count; +static int im_count; +static const route_head *rte_active; +static int start_new; + +#define MYNAME "GTM" +#define EPOCH89DIFF 631065600 +/* was 631076400 but that seems to include a three-hour bias */ +#define WAYPOINTSTYLES \ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x00\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x01\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x02\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + "\xf5\xff\xff\xff\x0f\x00Times New Roman\x03\x00\x00\x00\x00\x90\x01"\ + "\x00\x00\x00\x00\x00\x00\x8b\xff\xff\xff\xff\x00\x00\x00\x00\x00\x01" + +#define unknown_alt_gtm -10000000 + +/* Read functions, according to specification. */ + +static void +fread_discard(FILE *fd, int len) +{ + char buf[1024]; + fread(buf, 1, len, fd); +} + +static unsigned char +fread_byte(FILE *fd) +{ + unsigned char buf[1]; + fread(buf, 1, 1, fd); + return buf[0]; +} + +#if 0 +/* not used */ +static short int +fread_bool(FILE *fd) +{ + char buf[2]; + fread(buf, 2, 1, fd); + return le_read16(buf) ? 1 : 0; +} +#endif + +static short int +fread_integer(FILE *fd) +{ + char buf[2]; + fread(buf, 2, 1, fd); + return le_read16(buf); +} + +static int +fread_long(FILE *fd) +{ + char buf[4]; + fread(buf, 4, 1, fd); + return le_read32(buf); +} + +static float +fread_single(FILE *fd) +{ + unsigned char buf[4]; + float f; + int i; + fread(buf, 4, 1, fd); + i = le_read32(buf); + memcpy(&f, &i, 4); + return f; +} + +static double +fread_double(FILE *fd) +{ + char buf[8]; + fread(buf, 8, 1, fd); + return le_read_double(buf); +} + +static char * +fread_string(FILE *fd) +{ + int len = fread_integer(fd); + char *val; + + if (len == 0) return NULL; + + val = xmalloc(len+1); + fread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') + len--; + val[len] = 0; + return val; +} + +static void +fread_string_discard(FILE *fd) +{ + char *temp = fread_string(fd); + if (temp != NULL) { + xfree(temp); + } +} + +static char * +fread_fixedstring(FILE *fd, int len) +{ + char *val = xmalloc(len+1); + fread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') + len--; + val[len] = 0; + return val; +} + +/* Write functions, according to specification. */ + +static void +fwrite_null(FILE *fd, int len) +{ + char buf[1024]; + memset(buf, 0, len); + fwrite(buf, 1, len, fd); +} + +static void +fwrite_byte(FILE *fd, unsigned char val) +{ + fwrite(&val, 1, 1, fd); +} + +static void +fwrite_bool(FILE *fd, short int val) +{ + char buf[2]; + buf[0] = buf[1] = val ? 0xff : 0x00; + fwrite(buf, 2, 1, fd); +} + +static void +fwrite_integer(FILE *fd, short int val) +{ + char buf[2]; + le_write16(buf, val); + fwrite(buf, 2, 1, fd); +} + +static void +fwrite_long(FILE *fd, int val) +{ + char buf[4]; + le_write32(buf, val); + fwrite(buf, 4, 1, fd); +} + +static void +fwrite_single(FILE *fd, float val) +{ + char buf[4]; + int i; + memcpy(&i, &val, 4); + le_write32(buf, i); + fwrite(buf, 4, 1, fd); +} + +static void +fwrite_double(FILE *fd, double val) +{ + char buf[8]; + le_write_double(buf,val); + fwrite(buf, 8, 1, fd); +} + +static void +fwrite_string(FILE *fd, const char *str) +{ + if (str && str[0]) { + int len = strlen(str); + fwrite_integer(fd, len); + fwrite(str, 1, len, fd); + } + else { + fwrite_integer(fd, 0); + } +} + +void +fwrite_fixedstring(FILE *fd, const char *str, int fieldlen) +{ + int len = str ? strlen(str) : 0; + if (len > fieldlen) + len = fieldlen; + if (str) + fwrite(str, 1, len, fd); + for (; len != fieldlen; len++) + fputc(' ', fd); +} + +/* Auxiliar functions */ + +void +set_datum(int n) +{ + indatum = -1; + if (n < 1) {} + else if (n < 8) { indatum = 0; } /* Adindan */ + else if (n < 9) { indatum = 1; } /* Afgooye */ + else if (n < 10) { indatum = 2; } /* Ain el Abd */ + else if (n < 14) {} + else if (n < 23) { indatum = 6; } /* ARC 1950 */ + else if (n < 26) { indatum = 7; } /* ARC 1960 */ + else if (n < 27) { indatum = 8; } /* Ascension Island 58 */ + else if (n < 32) {} + else if (n < 33) { indatum = 13; } /* Australian Geo 84 */ + else if (n < 34) {} + else if (n < 35) { indatum = 15; } /* Bellevue IGN */ + else if (n < 36) { indatum = 16; } /* Bermuda 1957 */ + else if (n < 38) {} + else if (n < 39) { indatum = 17; } /* Bukit Rimpah */ + else if (n < 40) { indatum = 18; } /* Camp Area Astro */ + else if (n < 41) { indatum = 19; } /* Campo Inchauspe */ + else if (n < 42) { indatum = 22; } /* Canton Islan 1966 */ + else if (n < 43) { indatum = 23; } /* Cape */ + else if (n < 44) { indatum = 24; } /* Cape Canaveral */ + else if (n < 45) { indatum = 26; } /* Carthe */ + else if (n < 46) { indatum = 28; } /* Chatham */ + else if (n < 47) { indatum = 29; } /* Chua Astro */ + else if (n < 48) { indatum = 30; } /* Corrego Alegre*/ + else if (n < 50) {} + else if (n < 51) { indatum = 33; } /* Djakarta (Batavia) */ + else if (n < 52) { indatum = 34; } /* DOS 1968 */ + else if (n < 53) { indatum = 35; } /* Easter Island 1967 */ + else if (n < 54) {} + else if (n < 69) { indatum = 38; } /* European 1950 Mean */ + else if (n < 70) { indatum = 39; } /* European 1979 Mean */ + else if (n < 71) {} + else if (n < 72) { indatum = 41; } /* Gandajika */ + else if (n < 73) { indatum = 42; } /* Geodetic Datum 49 */ + else if (n < 74) {} + else if (n < 75) { indatum = 45; } /* Guam 1963 */ + else if (n < 76) { indatum = 46; } /* Gunung Segara */ + else if (n < 77) {} + else if (n < 78) { indatum = 49; } /* Hearth North */ + else if (n < 79) {} + else if (n < 80) { indatum = 50; } /* Hjorsey 1955 */ + else if (n < 81) { indatum = 51; } /* Hong Kong 1963 */ + else if (n < 82) { indatum = 52; } /* Hu-Tzu-Shan */ + else if (n < 89) { indatum = 53; } /* Indian */ + else if (n < 90) {} + else if (n < 91) { indatum = 55; } /* Ireland 1965 */ + else if (n < 92) {} + else if (n < 93) { indatum = 56; } /* ISTS 073 69 */ + else if (n < 94) { indatum = 57; } /* Johnston Island 61 */ + else if (n < 95) { indatum = 58; } /* Kandawala */ + else if (n < 96) { indatum = 59; } /* Kerguelen Island */ + else if (n < 97) { indatum = 60; } /* Kertau 48 */ + else if (n < 99) {} + else if (n < 100) { indatum = 61; } /* L.C. 5 Astro */ + else if (n < 101) {} + else if (n < 102) { indatum = 63; } /* Liberia 1964 */ + else if (n < 104) { indatum = 64; } /* Luzon */ + else if (n < 105) {} + else if (n < 106) { indatum = 65; } /* Mahe 1971 */ + else if (n < 107) {} + else if (n < 108) { indatum = 69; } /* Merchich */ + else if (n < 109) { indatum = 71; } /* Midway Astro 61 */ + else if (n < 111) { indatum = 73; } /* Minna */ + else if (n < 112) {} + else if (n < 115) { indatum = 75; } /* Nahrwan */ + else if (n < 116) { indatum = 76; } /* Naparima BWI */ + else if (n < 116) {} + else if (n < 119) { indatum = 3; } /* Alaska NAD27 */ + else if (n < 121) { indatum = 14; } /* Bahamas NAD27 */ + else if (n < 126) { indatum = 20; } /* Canada Mean NAD27 */ + else if (n < 127) { indatum = 21; } /* Canal Zone NAD27 */ + else if (n < 128) { indatum = 31; } /* Cuba NAD27 */ + else if (n < 129) { indatum = 44; } /* Greenland NAD27 */ + else if (n < 131) {} + else if (n < 132) { indatum = 20; } /* Canada Mean NAD27 */ + else if (n < 135) {} + else if (n < 136) { indatum = 70; } /* Mexico NAD27 */ + else if (n < 144) {} + else if (n < 145) { indatum = 80; } /* Old Egyptian */ + else if (n < 146) { indatum = 81; } /* Old Hawaiian */ + else if (n < 147) { indatum = 82; } /* Old Hawaiian Kauai */ + else if (n < 148) { indatum = 83; } /* Old Hawaiian Maui */ + else if (n < 149) { indatum = 81; } /* Old Hawaiian Mean */ + else if (n < 150) { indatum = 84; } /* Old Hawaiian Oahu */ + else if (n < 151) { indatum = 85; } /* Oman */ + else if (n < 156) { indatum = 86; } /* OSG Britain */ + else if (n < 157) { indatum = 87; } /* Pico de Las Nieves */ + else if (n < 158) { indatum = 88; } /* Pitcairn Astro 67 */ + else if (n < 171) {} + else if (n < 172) { indatum = 91; } /* Puerto Rico */ + else if (n < 173) { indatum = 92; } /* Pulkovo 1942 */ + else if (n < 174) { indatum = 94; } /* Quatar National */ + else if (n < 176) {} + else if (n < 177) { indatum = 95; } /* Rome 1940 */ + else if (n < 184) { indatum = 96; } /* S-42 (Pulkovo 1942) */ + else if (n < 185) {} + else if (n < 186) { indatum = 100; } /* Santo DOS */ + else if (n < 187) { indatum = 99; } /* Sao Braz */ + else if (n < 191) {} + else if (n < 193) { indatum = 105; } /* SAD-69/Mean */ + else if (n < 194) { indatum = 98; } /* SAD-69/Brazil */ + else if (n < 204) { indatum = 105; } /* SAD-69/Mean */ + else if (n < 205) { indatum = 106; } /* South Asia */ + else if (n < 206) { indatum = 109; } /* Tananarive 1926 */ + else if (n < 207) { indatum = 111; } /* Timbalai 1948 */ + else if (n < 211) { indatum = 112; } /* Tokyo mean */ + else if (n < 212) { indatum = 113; } /* Tristan Astro 1968 */ + else if (n < 213) { indatum = 115; } /* Viti Levu 1916 */ + else if (n < 215) {} + else if (n < 216) { indatum = 116; } /* Wake Eniwetok 1960 */ + else if (n < 217) { indatum = 117; } /* WGS 72 */ + else if (n < 218) { indatum = 118; } /* WGS 84 */ + else if (n < 219) { indatum = 119; } /* Yacare */ + else if (n < 220) { indatum = 120; } /* Zanderij */ + else if (n < 231) {} + else if (n < 232) { indatum = 98; } /* SAD-69/Brazil*/ + else if (n < 234) {} + else if (n < 235) { indatum = 117; } /* WGS 72 */ + else if (n < 236) { indatum = 0; } /* Adindan */ + else if (n < 237) { indatum = 2; } /* Ain el Abd */ + else if (n < 238) { indatum = 7; } /* ARC 1960 */ + else if (n < 239) { indatum = 8; } /* Ascension Island 58 */ + else if (n < 241) {} + else if (n < 242) { indatum = 52; } /* Hu-Tzu-Shan */ + else if (n < 245) { indatum = 53; } /* Indian */ + else if (n < 246) {} + else if (n < 247) { indatum = 57; } /* Johnston Island 61 */ + else if (n < 248) { indatum = 64; } /* Luzon */ + else if (n < 249) {} + else if (n < 250) { indatum = 75; } /* Nahrwan */ + else if (n < 251) { indatum = 76; } /* Naparima BWI */ + else if (n < 254) {} + else if (n < 255) { indatum = 82; } /* Old Hawaiian Kauai */ + else if (n < 256) { indatum = 83; } /* Old Hawaiian Maui */ + else if (n < 257) { indatum = 84; } /* Old Hawaiian Oahu */ + else if (n < 259) {} + else if (n < 260) { indatum = 101; } /* Sapper Hill 43 */ + else if (n < 261) { indatum = 111; } /* Timbalai 1948 */ + else if (n < 262) { indatum = 112; } /* Tokyo mean */ + else if (n < 263) { indatum = 116; } /* Wake Eniwetok 1960 */ + + if (indatum == -1) + warning(MYNAME ": Unsupported datum (%d), won't convert to WGS84\n", n); +} + +static const char *icon_descr[] = { +"", "Airport", "Ball Park", "Bank", "Bar", "Boat Ramp", "Campground", "Car", +"City (Large)", "City (Medium)", "City (Small)", "Dam", "Danger Area", +"Drinking Water", "Fishing Area", "Gas Station", "Glider Area", "Golf Course", +"Heliport", "Hotel", "Animals", "Information", "Man Overboard", "Marina", +"Mine", "Medical Facility", "Parachute Area", "Park", "Parking Area", +"Picnic Area", "Private Field", "Residence", "Restaurant", "Restroom", +"Scenic Area", "School", "Seaplane Base", "Shipwreck", "Shopping Center", +"Short Tower", "Policy Station", "Ski Resort", "Soft Field", "Swimming Area", +"Tall Tower", "Telephone", "Tracback Point", "Ultralight Area", "Waypoint", +"Boat", "Exit", "Flag", "Duck", "Buoy", "Back Track", "Beach", "Bridge", +"Building", "Car Repair", "Cemetery", "Church", "Civil", "Convenience Store", +"Crossing", "Fast Food", "Forest", "Ghost Town", "Levee", "Military", +"Oil Field", "Post Office", "Rv Park", "Scales", "Summit", "Toll Booth", +"Trail Head", "Truck Stop", "Tunnel", "Highway", "Gate", "Fall", "Fence", +"Mata-Burro", "Fitness Center", "Movie Theater", "Live Theater", "Zoo", "Horn", +"Bowling", "Car Rental", "City (Capitol)", "Controlled Area", "Stadium", +"Museum", "Amusement Park", "Skull", "Department Store", "Pharmacy", "Pizza", +"Diver Down Flag 1", "Light", "Pin", "", "Pigsty", "Tree", "Bamboo", +"Banana Plant", "Arrow-Down", "Bifurcation", "Cavern", "River", "Rock", +"Arrow-Up", "Trunk", "Soccer Field", "Sporting Court", "Flag, Green", "Trench", +"Ship-Yellow", "Green Sign", "Swamp", "Lake", "Stop!", +"Fishing Hot Spot Facility", "Speed Reducer", "Stairway", "Cactus", "Ship-Red", +"Letter - S", "Letter - D", "Letter - N", +"Crossing", "Cross", "Flag, Red", "Curve1", "Curve2", "Curve3", "Curve4", +"Letter - W", "Letter - L", "Letter - R", "Radio Beacon", "Road Sign", +"Geocache", "Geocache Found", "Traffic Light", "Bus Station", "Train Station", +"School", "Mile Marker", "Conservation Area", "Waypoint", "Box", "Aerial", +"Auto Repair", "Boat", "Exit Ramp", "Fixed Nav Aid", "Floating Buoy", "Garden", +"Fish Farm", "Lighthouse", "Truck Service", "Resort", "Scuba", "Shooting", +"Sight Seeing", "Sounding", "Winery", "Navaid, Amber", "Navaid, Black", +"Navaid, Blue", "Navaid, Green", "Navaid, Green/Red", "Navaid, Green/White", +"Navaid, Orange", "Navaid, Red", "Navaid, Red/Green", "Navaid, Red/White", +"Navaid, Violet", "Navaid, White", "Navaid, White/Green", "Navaid, White/Red", +"Buoy, White", "Dot, White", "Red Square", "Red Diamond", "Green Square", +"Green Diamond", "Restricted Area", "Navaid (unlit)", "Dot (Small)", "Libraries", "Waypoint", "Waypoint1", +"Waypoint2", "Mark (1)", "Mark (2)", "Mark (3)", "Cross (Red)", "Store", +"Exclamation", "Flag (EUA)", "Flag (CAN)", "Flag (BRA)", "Man", "Animals", +"Deer Tracks", "Tree Stand", "Bridge", "Fence", "Intersection", +"Non Direct Beacon", "VHF Omni Range", "Vor/Tacan", "Vor-Dme", +"1st Approach Fix", "Localizer Outer", "Missed Appr. Pt", "Tacan", +"CheckPoint", NULL +}; + + +void convert_datum(double *lat, double *lon) +{ + double amt; + if (indatum != -1 && indatum != 118) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, + lat, lon, &amt, indatum); + } +} + +/* Callbacks */ + +static void +gtm_rd_init(const char *fname) +{ + int version; + char *name; + fd = xfopen(fname, "rb", MYNAME); + version = fread_integer(fd); + name = fread_fixedstring(fd, 10); + if (version == -29921) + fatal(MYNAME ": Uncompress the file first\n"); + if (strcmp(name, "TrackMaker") != 0) + fatal(MYNAME ": Invalid file format\n"); + if (version != 211) + fatal(MYNAME ": Invalid format version\n"); + xfree(name); + + /* Header */ + fread_discard(fd, 15); + ws_count = fread_long(fd); + fread_discard(fd, 4); + wp_count = fread_long(fd); + tr_count = fread_long(fd); + rt_count = fread_long(fd); + fread_discard(fd, 16); + im_count = fread_long(fd); + ts_count = fread_long(fd); + fread_discard(fd, 28); + fread_string_discard(fd); + fread_string_discard(fd); + fread_string_discard(fd); + fread_string_discard(fd); + + /* User Grid and Datum */ + fread_discard(fd, 34); + set_datum(fread_integer(fd)); + fread_discard(fd, 22); +} + +static void +gtm_rd_deinit(void) +{ + fclose(fd); +} + +static void count_route_waypts(const waypoint *wpt) { rt_count++; } +static void count_track_waypts(const waypoint *wpt) { tr_count++; } + +static void +gtm_wr_init(const char *fname) +{ + rt_count = tr_count = 0; + track_disp_all(NULL, NULL, count_track_waypts); + route_disp_all(NULL, NULL, count_route_waypts); + + ofd = xfopen(fname, "wb", MYNAME); + + /* Header */ + fwrite_integer(ofd, 211); + fwrite_fixedstring(ofd, "TrackMaker", 10); + fwrite_byte(ofd, 0); + fwrite_byte(ofd, 0); + fwrite_byte(ofd, 8); + fwrite_byte(ofd, 0); + fwrite_byte(ofd, 0); + fwrite_byte(ofd, 0); + fwrite_byte(ofd, 0); + fwrite_long(ofd, 0); + fwrite_long(ofd, 16777215); + fwrite_long(ofd, waypt_count() ? 4 : 0); /* num waypoint styles */ + fwrite_long(ofd, 0); + fwrite_long(ofd, waypt_count()); /* num waypoints */ + fwrite_long(ofd, tr_count); + fwrite_long(ofd, rt_count); + fwrite_single(ofd, 0); /* maxlon */ + fwrite_single(ofd, 0); /* minlon */ + fwrite_single(ofd, 0); /* maxlat */ + fwrite_single(ofd, 0); /* minlat */ + fwrite_long(ofd, 0); + fwrite_long(ofd, track_count()); /* num tracklog styles */ + fwrite_single(ofd, 0); + fwrite_single(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_bool(ofd, 0); + fwrite_string(ofd, "Times New Roman"); + fwrite_string(ofd, ""); + fwrite_string(ofd, ""); + fwrite_string(ofd, ""); + + /* User Grid and Datum */ + fwrite_null(ofd, 34); + fwrite_integer(ofd, 217); /* WGS84 */ + fwrite_null(ofd, 22); +} + +static void +gtm_wr_deinit(void) +{ + fclose(ofd); +} + +static void +gtm_read(void) +{ + route_head *first_trk_head = NULL; + route_head *trk_head = NULL; + route_head *rte_head = NULL; + waypoint *wpt; + int real_tr_count = 0; + char *route_name; + unsigned int icon; + int i; + + /* Image information */ + for (i = 0; i != im_count; i++) { + fread_string_discard(fd); + fread_string_discard(fd); + fread_discard(fd, 30); + } + + /* Waypoints */ + for (i = 0; i != wp_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(fd); + wpt->longitude = fread_double(fd); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(fd, 10); + wpt->description = fread_string(fd); + icon = fread_integer(fd); + if (icon < sizeof(icon_descr)/sizeof(char*)) + wpt->icon_descr = icon_descr[icon]; + fread_discard(fd, 1); + wpt->creation_time = fread_long(fd); + if (wpt->creation_time) + wpt->creation_time += EPOCH89DIFF; + fread_discard(fd, 2); + wpt->altitude = fread_single(fd); + if (wpt->altitude == unknown_alt_gtm) + wpt->altitude = unknown_alt; + fread_discard(fd, 2); + waypt_add(wpt); + } + + /* Waypoint Styles */ + if (wp_count) { + for (i = 0; i != ws_count; i++) { + fread_discard(fd, 4); + fread_string_discard(fd); + fread_discard(fd, 24); + } + } + + /* Tracklogs */ + for (i = 0; i != tr_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(fd); + wpt->longitude = fread_double(fd); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->creation_time = fread_long(fd); + if (wpt->creation_time) + wpt->creation_time += EPOCH89DIFF; + start_new = fread_byte(fd); + wpt->altitude = fread_single(fd); + if (wpt->altitude == unknown_alt_gtm) + wpt->altitude = unknown_alt; + if (start_new || !trk_head) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + real_tr_count++; + if (!first_trk_head) + first_trk_head = trk_head; + } + track_add_wpt(trk_head, wpt); + } + + /* Tracklog styles */ + trk_head = first_trk_head; + for (i = 0; i != ts_count && i != real_tr_count; i++) { + trk_head->rte_name = fread_string(fd); + fread_discard(fd, 12); + trk_head = (route_head *)QUEUE_NEXT(&trk_head->Q); + } + + /* Routes */ + for (i = 0; i != rt_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(fd); + wpt->longitude = fread_double(fd); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(fd, 10); + wpt->description = fread_string(fd); + route_name = fread_string(fd); + icon = fread_integer(fd); + if (icon < sizeof(icon_descr)/sizeof(char*)) + wpt->icon_descr = icon_descr[icon]; + fread_discard(fd, 1); + start_new = fread_byte(fd); + fread_discard(fd, 6); + wpt->altitude = fread_single(fd); + if (wpt->altitude == unknown_alt_gtm) + wpt->altitude = unknown_alt; + fread_discard(fd, 2); + + if (start_new || !rte_head) { + rte_head = route_head_alloc(); + rte_head->rte_name = route_name; + route_add_head(rte_head); + } + else { + xfree(route_name); + } + route_add_wpt(rte_head, wpt); + } +} + +int icon_from_descr(const char *descr) +{ + if (descr) { + int i; + for (i = 0; icon_descr[i]; i++) + if (strcmp(icon_descr[i], descr) == 0) + return i; + } + return 48; +} + +static void write_waypt(const waypoint *wpt) +{ + fwrite_double(ofd, wpt->latitude); + fwrite_double(ofd, wpt->longitude); + fwrite_fixedstring(ofd, wpt->shortname, 10); + fwrite_string(ofd, wpt->description); + fwrite_integer(ofd, icon_from_descr(wpt->icon_descr)); + fwrite_byte(ofd, 3); + if (wpt->creation_time) + fwrite_long(ofd, wpt->creation_time-EPOCH89DIFF); + else + fwrite_long(ofd, 0); + fwrite_integer(ofd, 0); + if (wpt->altitude == unknown_alt) + fwrite_single(ofd, unknown_alt_gtm); + else + fwrite_single(ofd, wpt->altitude); + fwrite_integer(ofd, 0); +} + +static void start_rte(const route_head *rte) +{ + rte_active = rte; + start_new = 1; +} + +static void write_trk_waypt(const waypoint *wpt) +{ + fwrite_double(ofd, wpt->latitude); + fwrite_double(ofd, wpt->longitude); + fwrite_long(ofd, wpt->creation_time-EPOCH89DIFF); + fwrite_byte(ofd, start_new); + if (wpt->altitude == unknown_alt) + fwrite_single(ofd, unknown_alt_gtm); + else + fwrite_single(ofd, wpt->altitude); + start_new = 0; +} + +static void write_trk_style(const route_head *trk) +{ + fwrite_string(ofd, trk->rte_name); + fwrite_byte(ofd, 1); + fwrite_long(ofd, 0); + fwrite_single(ofd, 0); + fwrite_byte(ofd, 0); + fwrite_integer(ofd, 0); +} + +static void write_rte_waypt(const waypoint *wpt) +{ + fwrite_double(ofd, wpt->latitude); + fwrite_double(ofd, wpt->longitude); + fwrite_fixedstring(ofd, wpt->shortname, 10); + fwrite_string(ofd, wpt->description); + fwrite_string(ofd, rte_active->rte_name); + fwrite_integer(ofd, icon_from_descr(wpt->icon_descr)); + fwrite_byte(ofd, 3); + fwrite_byte(ofd, start_new); + fwrite_long(ofd, 0); + fwrite_integer(ofd, 0); + if (wpt->altitude == unknown_alt) + fwrite_single(ofd, unknown_alt_gtm); + else + fwrite_single(ofd, wpt->altitude); + fwrite_integer(ofd, 0); + start_new = 0; +} + +static void +gtm_write(void) +{ + waypt_disp_all(write_waypt); + if (waypt_count()) + fwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, ofd); + track_disp_all(start_rte, NULL, write_trk_waypt); + track_disp_all(write_trk_style, NULL, NULL); + route_disp_all(start_rte, NULL, write_rte_waypt); +} + +static +arglist_t gtm_args[] = { + ARG_TERMINATOR +}; + +ff_vecs_t gtm_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + gtm_rd_init, + gtm_wr_init, + gtm_rd_deinit, + gtm_wr_deinit, + gtm_read, + gtm_write, + NULL, + gtm_args, +}; diff --git a/gtrnctr.c b/gtrnctr.c new file mode 100644 index 000000000..b3885131f --- /dev/null +++ b/gtrnctr.c @@ -0,0 +1,306 @@ +/* + Access Garmin Training Center (Forerunner/Foretracker/Edge) data files. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static FILE *ofd; +static waypoint *wpt_tmp; +static route_head *trk_head; + +#define MYNAME "gtc" + +static +arglist_t gtc_args[] = { + ARG_TERMINATOR +}; +#if 0 +/* Tracks */ +static xg_callback gl_trk_s; +// static xg_callback gl_trk_ident; +static xg_callback gl_trk_pnt_s, gl_trk_pnt_e; +static xg_callback gl_trk_utc; +static xg_callback gl_trk_lat; +static xg_callback gl_trk_long; +static xg_callback gl_trk_alt; + +static xg_tag_mapping gl_map[] = { + { gl_trk_s, cb_start, "/History/Run/Track" }, + { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, + { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, + { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, + { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, + { NULL, 0, NULL} +}; +#endif + +static void +gtc_rd_init(const char *fname) +{ + fatal(MYNAME ": this format does not support reading.\n"); +} + +#if 0 +static void +gtc_read(void) +{ + xml_read(); +} + +static void +gtc_rd_deinit(void) +{ + xml_deinit(); +} +#endif + +static void +gtc_wr_init(const char *fname) +{ + ofd = xfopen(fname, "w", MYNAME); +} + +static void +gtc_wr_deinit(void) +{ + fclose(ofd); +} + +static int gtc_indent_level; +static void +gtc_write_xml(int indent, const char *fmt, ...) +{ + va_list args; + int i; + va_start(args, fmt); + + if (indent < 0) gtc_indent_level--; + + for (i = 0; i < gtc_indent_level; i++) { + fputs(" ", ofd); + } + + vfprintf(ofd, fmt, args); + + if (indent > 0) gtc_indent_level++; + + va_end(args); + +} + +static void +gtc_waypt_pr(const waypoint *wpt) +{ +#if 0 + fprintf(ofd, " \n"); + fprintf(ofd, " \n"); + fprintf(ofd, " %.5f\n", wpt->latitude); + fprintf(ofd, " %.5f\n", wpt->longitude); + if (wpt->altitude != unknown_alt) { + fprintf(ofd, " %.3f\n", wpt->altitude); + } + fprintf(ofd, " \n"); + fprintf(ofd, " "); + xml_write_time(ofd, wpt->creation_time, "Time"); + fprintf(ofd, " \n"); +#else + gtc_write_xml(1, "\n"); + if (wpt->creation_time) { + char time_string[100]; + xml_fill_in_time(time_string, wpt->creation_time, + XML_LONG_TIME); + if (time_string[0]) { + gtc_write_xml(0, "\n", + time_string); + } + } + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%f\n", wpt->latitude); + gtc_write_xml(0, "%f\n", wpt->longitude); + gtc_write_xml(-1, "\n"); + if (wpt->altitude != unknown_alt) { + gtc_write_xml(0, "%f\n", wpt->altitude); + } + if (wpt->heartrate) { + gtc_write_xml(0, "%d\n", wpt->heartrate); + } + if (wpt->cadence) { + gtc_write_xml(0, "%d\n", wpt->cadence); + } + + + gtc_write_xml(-1, "\n"); +#endif +} + +static void +gtc_hdr( const route_head *rte) +{ + gtc_write_xml(1,"\n"); +} + +static void +gtc_ftr(const route_head *rte) +{ + gtc_write_xml(-1,"\n"); +} + +static time_t gtc_least_time; +static time_t gtc_most_time; + +static void +gtc_lap_start(const route_head *rte) +{ + gtc_least_time = 0; + gtc_most_time = 0; +} + +static void +gtc_study_lap(const waypoint *wpt) +{ + if (wpt->creation_time && (gtc_least_time == 0)) + gtc_least_time = wpt->creation_time; + + if (wpt->creation_time && (gtc_least_time > wpt->creation_time)) + gtc_least_time = wpt->creation_time; + + if (wpt->creation_time > gtc_most_time) + gtc_most_time = wpt->creation_time; +} + +static void +gtc_fake_hdr(void) +{ + long secs = 0; + if (gtc_least_time && gtc_most_time) { + secs = gtc_most_time - gtc_least_time; + } + gtc_write_xml(0, "%d\n", secs); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "Active\n"); + gtc_write_xml(0, "Manual\n"); +} + +void +gtc_write(void) +{ +#if 0 + fprintf(ofd, "\n"); + fprintf(ofd, "\n"); + fprintf(ofd, " \n"); + track_disp_all(gtc_hdr, gtc_ftr, gtc_waypt_pr); + fprintf(ofd, " \n"); + fprintf(ofd, "\n"); +#else + gtc_write_xml(0, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(1, "\n"); + + gtc_write_xml(1, "\n"); + gtc_write_xml(1, "\n"); + + gtc_lap_start(NULL); + track_disp_all(NULL, NULL, gtc_study_lap); + + if (gtc_least_time) { + char time_string[100]; + xml_fill_in_time(time_string, gtc_least_time, XML_LONG_TIME); + gtc_write_xml(1, "\n", time_string); + } else { + gtc_write_xml(1, "\n"); + } + gtc_fake_hdr(); + track_disp_all(gtc_hdr, gtc_ftr, gtc_waypt_pr); + gtc_write_xml(1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(0, "\n"); + gtc_write_xml(0, "\n"); + gtc_write_xml(0, "\n"); + + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + +#endif +} + +void gl_trk_s(const char *args, const char **unused) +{ + trk_head = route_head_alloc(); + track_add_head(trk_head); +} +#if 0 +void gl_trk_ident(const char *args, const char **unused) +{ + trk_head->rte_name = xstrdup(args); +} +#endif + +void gl_trk_pnt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +void gl_trk_pnt_e(const char *args, const char **unused) +{ + track_add_wpt(trk_head, wpt_tmp); +} + +void gl_trk_utc(const char *args, const char **unused) +{ + wpt_tmp->creation_time = xml_parse_time(args); +} + +void gl_trk_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +void gl_trk_long(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +void gl_trk_alt(const char *args, const char **unused) +{ + wpt_tmp->altitude = atof(args); +} + + + +ff_vecs_t gtc_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_write, ff_cap_none}, + gtc_rd_init, + gtc_wr_init, + NULL, + gtc_wr_deinit, + NULL, + gtc_write, + NULL, + gtc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/guibabel b/guibabel index d0197df23..6afd8a5ed 100644 --- a/guibabel +++ b/guibabel @@ -54,7 +54,7 @@ foreach i {read write} { # TODO: Get this list from 'gpsbabel -?' instead of hardcoding it here. tk_optionMenu $f.ftypes $ftype geo gpsman gpx \ magellan mapsend pcx mapsource gpsutil tiger csv xmap dna psp \ - cetus gpspilot magnav garmin mxf holux ozi tpg igc baroiq + cetus gpspilot magnav garmin mxf holux ozi tpg tpo igc baroiq pack $f.lab -side left pack $f.ent -side left -expand yes -fill x pack $f.but -side left diff --git a/hiketech.c b/hiketech.c index 4daa056bd..c8e0ccced 100644 --- a/hiketech.c +++ b/hiketech.c @@ -31,7 +31,7 @@ static route_head *trk_head; static arglist_t hiketech_args[] = { - {0, 0, 0, 0, 0} + ARG_TERMINATOR }; /* Waypoints */ @@ -79,24 +79,25 @@ hiketech_rd_init(const char *fname) xml_init(fname, ht_map, NULL); } -void +static void hiketech_read(void) { xml_read(); } -void +static void hiketech_rd_deinit(void) { + xml_deinit(); } -void +static void hiketech_wr_init(const char *fname) { ofd = xfopen(fname, "w", MYNAME); } -void +static void hiketech_wr_deinit(void) { fclose(ofd); @@ -240,7 +241,7 @@ void ht_trk_pnt_s(const char *args, const char **unused) static void ht_trk_pnt_e(const char *args, const char **unused) { - route_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } static @@ -292,6 +293,7 @@ ff_vecs_t hiketech_vecs = { hiketech_read, hiketech_write, NULL, - hiketech_args + hiketech_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/holux.c b/holux.c index 03613ff7f..df475d6c9 100644 --- a/holux.c +++ b/holux.c @@ -34,7 +34,7 @@ History: static FILE *file_in; static unsigned char *HxWFile; -static void *mkshort_handle; +static short_handle mkshort_handle; static char fOutname[256]; #define MYNAME "Holux" @@ -70,7 +70,7 @@ wr_init(const char *fname) static void wr_deinit(void) { - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } @@ -90,6 +90,7 @@ static void data_read(void) struct tm tm; struct tm *ptm; + memset(&tm, 0, sizeof(tm)); HxWpt = xcalloc(GM100_WPO_FILE_SIZE, 1); @@ -124,15 +125,25 @@ static void data_read(void) wpt_tmp->creation_time = 0; if (pWptHxTmp->date.year) { +#if 0 + /* Unless there's some endian swapping that I don't see, + * this can't be right. Then again, the definition of the + * the structure itself has a pretty serious disregard for + * host word size issues... - rjl + */ ptm = gmtime((time_t*)&pWptHxTmp->time); - tm.tm_hour = ptm->tm_hour; - tm.tm_min = ptm->tm_min; - tm.tm_sec = ptm->tm_sec; - - tm.tm_mday = pWptHxTmp->date.day; - tm.tm_mon = pWptHxTmp->date.month - 1; - tm.tm_year = pWptHxTmp->date.year - 1900; - wpt_tmp->creation_time = mktime(&tm); +#else + time_t wt = le_read32(&pWptHxTmp->time); + ptm = gmtime(&wt); +#endif + tm.tm_hour = ptm->tm_hour; + tm.tm_min = ptm->tm_min; + tm.tm_sec = ptm->tm_sec; + + tm.tm_mday = pWptHxTmp->date.day; + tm.tm_mon = pWptHxTmp->date.month - 1; + tm.tm_year = pWptHxTmp->date.year - 1900; + wpt_tmp->creation_time = mktime(&tm); } lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; @@ -187,9 +198,8 @@ static void holux_disp(const waypoint *wpt) /* round it to increase the accuracy */ - lon += (double)((int)lon/abs((int)lon)) * .5; - lat += (double)((int)lat/abs((int)lat)) * .5; - + if (lon != 0) lon += (double)((int)lon/abs((int)lon)) * .5; + if (lat != 0) lat += (double)((int)lat/abs((int)lat)) * .5; sIndex = le_read16(&((WPTHDR *)HxWFile)->num); ((WPTHDR *)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ @@ -298,5 +308,7 @@ ff_vecs_t holux_vecs = { wr_deinit, data_read, data_write, - NULL + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/hsa_ndv.c b/hsa_ndv.c index 9fb6a73a7..bb85c71c7 100644 --- a/hsa_ndv.c +++ b/hsa_ndv.c @@ -17,7 +17,8 @@ */ #include "defs.h" -#if !NO_EXPAT +#include "cet_util.h" +#if HAVE_LIBEXPAT #include static XML_Parser psr; #endif @@ -28,21 +29,22 @@ static int in_ChartWork = 0; static int in_Object = 0; static waypoint *wpt_tmp; -char *routeName = "ROUTENAME"; +static char *routeName = "ROUTENAME"; #define REPLACEMENT_SIRIUS_ATTR_SEPARATOR ';' #define ATTR_USRMRK "usrmrk" #define ATTR_OBJECTNAME "OBJNAM" #define ATTR_SHIPNAME "shpnam" -void readVersion4( FILE* pFile); +static void readVersion4( FILE* pFile); +static void getAttr(const char *data, const char *attr, char **val, char seperator); -FILE *fd; -FILE *ofd; +static FILE *fd; +static FILE *ofd; static arglist_t hsa_ndv_args[] = { - {0, 0, 0, 0, 0} + ARG_TERMINATOR }; #define MYNAME "HsaNdv" @@ -52,22 +54,24 @@ arglist_t hsa_ndv_args[] = { #define FALSE 0 -#if NO_EXPAT -void +#if ! HAVE_LIBEXPAT +static void hsa_ndv_rd_init(const char *fname) { fatal(MYNAME ": This build excluded HSA Endeavour support because expat was not installed.\n"); } -void +static void hsa_ndv_read(void) { } #else static void -hsa_ndv_start(void *data, const char *el, const char **attr) +hsa_ndv_start(void *data, const XML_Char *xml_el, const XML_Char **attr) { + const char *el = xml_convert_to_char_string(xml_el); + // printf("<%s>\n", el); if (strcmp(el, "Export") == 0) {//should only be one @@ -88,38 +92,13 @@ hsa_ndv_start(void *data, const char *el, const char **attr) } //reset data :) memset(cdatastr,0, MY_CBUF); -} - -static void getAttr(const char *data, const char *attr, char **val, char seperator) -{ - char *start; - if ((start = strstr(data, attr)) != NULL) - { - char *end; - int len; - - end = strchr(start, seperator); - if (end == NULL) - { - end = start + strlen(start);//assume we are teh last attr - } - - len = end-start - strlen(attr); - - *val = xcalloc(len+1, 1); - memcpy(*val, start+strlen(attr), len); - (*val)[len] = '\0'; - } - else - { - *val = xcalloc(1, 1); - (*val)[0] = '\0'; - } + xml_free_converted_string(el); } static void -hsa_ndv_end(void *data, const char *el) +hsa_ndv_end(void *data, const XML_Char *xml_el) { + const char *el = xml_convert_to_char_string(xml_el); if (in_Route) { if (strcmp(el, "Version") == 0) @@ -216,6 +195,7 @@ hsa_ndv_end(void *data, const char *el) { in_ChartWork--; } + xml_free_converted_string(el); } static void @@ -226,7 +206,7 @@ hsa_ndv_cdata(void *dta, const XML_Char *s, int len) memcpy(estr, s, len); } -void +static void hsa_ndv_rd_init(const char *fname) { fd = xfopen(fname, "r", MYNAME); @@ -236,12 +216,13 @@ hsa_ndv_rd_init(const char *fname) fatal(MYNAME ":Cannot create XML parser\n"); } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); XML_SetElementHandler(psr, hsa_ndv_start, hsa_ndv_end); cdatastr = xcalloc(MY_CBUF,1); XML_SetCharacterDataHandler(psr, hsa_ndv_cdata); } -void +static void hsa_ndv_read(void) { int len; @@ -252,6 +233,7 @@ hsa_ndv_read(void) { char *bad; + buf[len-1] = 0; if (NULL != strstr(buf, "nver=1")) {//its the older format, not xml fseek(fd, 0, SEEK_SET); @@ -265,7 +247,7 @@ hsa_ndv_read(void) } if (!XML_Parse(psr, buf, len, feof(fd))) { fatal(MYNAME ":Parse error at %d: %s\n", - XML_GetCurrentLineNumber(psr), + (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); } } @@ -275,7 +257,33 @@ hsa_ndv_read(void) #endif -void +static void getAttr(const char *data, const char *attr, char **val, char seperator) +{ + char *start; + if ((start = strstr(data, attr)) != NULL) + { + char *end; + int len; + + end = strchr(start, seperator); + if (end == NULL) + { + end = start + strlen(start);//assume we are teh last attr + } + + len = end-start - strlen(attr); + + *val = xcalloc(len+1, 1); + memcpy(*val, start+strlen(attr), len); + (*val)[len] = '\0'; + } + else + { + *val = xcalloc(1, 1); + (*val)[0] = '\0'; + } +} +static void hsa_ndv_rd_deinit(void) { if ( cdatastr ) { @@ -284,13 +292,13 @@ hsa_ndv_rd_deinit(void) fclose(fd); } -void +static void hsa_ndv_wr_init(const char *fname) { ofd = xfopen(fname, "w", MYNAME); } -void +static void hsa_ndv_wr_deinit(void) { fclose(ofd); @@ -320,7 +328,7 @@ hsa_ndv_waypt_pr(const waypoint *waypointp) legNum++; } -void +static void hsa_ndv_write(void) { fprintf(ofd, "\n"); @@ -352,7 +360,8 @@ ff_vecs_t HsaEndeavourNavigator_vecs = { hsa_ndv_read, hsa_ndv_write, NULL, - hsa_ndv_args + hsa_ndv_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; ////////////////////////////////////////////////////////////////////////// @@ -370,10 +379,10 @@ ff_vecs_t HsaEndeavourNavigator_vecs = { #define INVALID_TIME -1L #define SOUNDARRAY_CHAR 'S' -int readRecord( FILE* pFile, const char* pRecName, char *recData); -int readPositionRecord( FILE* pFile, double* lat, double* lng, long* timeStamp); +static int readRecord( FILE* pFile, const char* pRecName, char *recData); +static int readPositionRecord( FILE* pFile, double* lat, double* lng, long* timeStamp); -void readVersion4( FILE* pFile) +static void readVersion4( FILE* pFile) { while( TRUE ) { @@ -472,7 +481,7 @@ void readVersion4( FILE* pFile) } // read a record to a file -int readRecord( FILE* pFile, const char* pRecName, char *recData) +static int readRecord( FILE* pFile, const char* pRecName, char *recData) { // get the rec name int len; @@ -517,7 +526,7 @@ int readRecord( FILE* pFile, const char* pRecName, char *recData) } // read position -int readPositionRecord( FILE* pFile, double* lat, double* lng, +static int readPositionRecord( FILE* pFile, double* lat, double* lng, long* timeStamp) { // read the lat record diff --git a/html.c b/html.c index 7fc724705..cadda3066 100644 --- a/html.c +++ b/html.c @@ -25,23 +25,29 @@ #include static FILE *file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; static char *stylesheet = NULL; -static char *encrypt = NULL; +static char *html_encrypt = NULL; static char *includelogs = NULL; +static char *degformat = NULL; +static char *altunits = NULL; #define MYNAME "HTML" static arglist_t html_args[] = { { "stylesheet", &stylesheet, - "Path to HTML style sheet", NULL, ARGTYPE_STRING }, - { "encrypt", &encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL }, + "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "encrypt", &html_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + { "degformat", °format, + "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX }, + { "altunits", &altunits, + "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; @@ -57,22 +63,21 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } static void html_disp(const waypoint *wpt) { - int latint, lonint; char tbuf[1024]; + char *cout; time_t tm = wpt->creation_time; - int32 utmz; + gbint32 utmz; double utme, utmn; char utmzc; fs_xml *fs_gpx = NULL; - lonint = abs((int) wpt->longitude); - latint = abs((int) wpt->latitude); + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, &utme, &utmn, &utmz, &utmzc); @@ -81,51 +86,64 @@ html_disp(const waypoint *wpt) strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - fprintf(file_out, "
\n"); - fprintf(file_out, "
\n", wpt->shortname); - fprintf(file_out, "

%s - %c%d°%06.3f %c%d°%06.3f (%ld%c %6.0f %7.0f)", - (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, - wpt->latitude < 0 ? 'S' : 'N', latint, 60.0 * (fabs(wpt->latitude) - latint), - wpt->longitude < 0 ? 'W' : 'E', lonint, 60.0 * (fabs(wpt->longitude) - lonint), - utmz, utmzc, utme, utmn); - if (wpt->altitude != unknown_alt) - fprintf (file_out, " alt: %1.1f", wpt->altitude); + fprintf(file_out, "\n
\n", wpt->shortname); + fprintf(file_out, "\n"); + fprintf(file_out, "\n"); + + fprintf (file_out, "\n"); + + + fprintf(file_out, "\n", DATA) +#define TD2(FMT,DATA, DATA2) kml_write_xml(0, "\n", DATA, DATA2) static arglist_t kml_args[] = { - {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING }, + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, {"lines", &opt_export_lines, "Export linestrings for tracks and routes", - "1", ARGTYPE_BOOL }, + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, {"points", &opt_export_points, "Export placemarks for tracks and routes", - "1", ARGTYPE_BOOL }, + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, {"line_width", &opt_line_width, "Width of lines, in pixels", - "6", ARGTYPE_BOOL }, + "6", ARGTYPE_INT, ARG_NOMINMAX }, {"line_color", &opt_line_color, "Line color, specified in hex AABBGGRR", - "64eeee17", ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + "64eeee17", ARGTYPE_STRING, ARG_NOMINMAX }, + {"floating", &opt_floating, + "Altitudes are absolute and not clamped to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"extrude", &opt_extrude, + "Draw extrusion line from trackpoint to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"trackdata", &opt_trackdata, + "Include extended data for trackpoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"units", &opt_units, + "Units used when writing comments ('s'tatute or 'm'etric)", + "s", ARGTYPE_STRING, ARG_NOMINMAX }, + {"labels", &opt_labels, + "Display labels on track and routepoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"max_position_points", &opt_max_position_points, + "Retain at most this number of position points (0 = unlimited)", + "0", ARGTYPE_INT, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static +struct { + int freshness; + char *icon; +} kml_tracking_icons[] = { + { 60, "http://maps.google.com/mapfiles/kml/pal4/icon15.png" }, // Red + { 30, "http://maps.google.com/mapfiles/kml/pal4/icon31.png" }, // Yellow + { 0, "http://maps.google.com/mapfiles/kml/pal4/icon62.png" }, // Green }; #define MYNAME "kml" -#if NO_EXPAT -void +#if ! HAVE_LIBEXPAT +static void kml_rd_init(const char *fname) { fatal(MYNAME ": This build excluded KML support because expat was not installed.\n"); } -void +static void kml_read(void) { } #else static xg_callback wpt_s, wpt_e; -static xg_callback wpt_name, wpt_desc, wpt_coord; +static xg_callback wpt_name, wpt_desc, wpt_coord, wpt_icon, trk_coord; static xg_tag_mapping kml_map[] = { - { wpt_s, cb_start, "/Document/Folder/Placemark" }, - { wpt_e, cb_end, "/Document/Folder/Placemark" }, - { wpt_name, cb_cdata, "/Document/Folder/Placemark/name" }, - { wpt_desc, cb_cdata, "/Document/Folder/Placemark/description" }, -// { wpt_type, cb_cdata, "/Folder/Placemark/type" }, -// { wpt_link_s, cb_start, "/Folder/Placemark/link" }, -// { wpt_link, cb_cdata, "/Folder/Placemark/link" }, - { wpt_coord, cb_cdata, "/Document/Folder/Placemark/Point/coordinates" }, + { wpt_s, cb_start, "/Placemark" }, + { wpt_e, cb_end, "/Placemark" }, + { wpt_name, cb_cdata, "/Placemark/name" }, + { wpt_desc, cb_cdata, "/Placemark/description" }, + { wpt_coord, cb_cdata, "/Placemark/Point/coordinates" }, + { wpt_icon, cb_cdata, "/Placemark/Style/Icon/href" }, + { trk_coord, cb_cdata, "/Placemark/MultiGeometry/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/LineString/coordinates" }, { NULL, 0, NULL } }; +static +const char * kml_tags_to_ignore[] = { + "kml", + "Document", + "Folder", + NULL, +}; + void wpt_s(const char *args, const char **unused) { wpt_tmp = waypt_new(); -// wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + wpt_tmp_queued = 0; } void wpt_e(const char *args, const char **unused) { - waypt_add(wpt_tmp); -} - -#if 0 -void wpt_name_s(const char *args, const char **attrv) -{ - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "id")) { - wpt_tmp->shortname = xstrdup(avp[1]); - } - avp+=2; - } + if (wpt_tmp_queued) { + waypt_add(wpt_tmp); + } + wpt_tmp_queued = 0; } -#endif void wpt_name(const char *args, const char **unused) { @@ -126,12 +171,51 @@ void wpt_name(const char *args, const char **unused) void wpt_desc(const char *args, const char **unused) { - if (args) wpt_tmp->description = xstrappend(wpt_tmp->description, args); + if (args) { + char *tmp, *c; + + tmp = xstrdup((char *)args); + c = lrtrim(tmp); + if (*c) { + wpt_tmp->description = xstrappend(wpt_tmp->description, c); + } + xfree(tmp); + } } void wpt_coord(const char *args, const char **attrv) { sscanf(args, "%lf,%lf,%lf", &wpt_tmp->longitude, &wpt_tmp->latitude, &wpt_tmp->altitude); + wpt_tmp_queued = 1; +} + +void wpt_icon(const char *args, const char **unused) +{ + if (wpt_tmp) { + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } +} + +void trk_coord(const char *args, const char **attrv) +{ + int consumed = 0; + double lat, lon, alt; + waypoint *trkpt; + + route_head *trk_head = route_head_alloc(); + track_add_head(trk_head); + + while (3 == sscanf(args,"%lf,%lf,%lf %n", &lon, &lat, &alt, &consumed)){ + trkpt = waypt_new(); + trkpt->latitude = lat; + trkpt->longitude = lon; + trkpt->altitude = alt; + + track_add_wpt(trk_head, trkpt); + + args += consumed; + } } static @@ -139,6 +223,7 @@ void kml_rd_init(const char *fname) { xml_init(fname, kml_map, NULL); + xml_ignore_tags(kml_tags_to_ignore); } static @@ -149,61 +234,266 @@ kml_read(void) } #endif -void +static void kml_rd_deinit(void) { xml_deinit(); } -void +static void kml_wr_init(const char *fname) { + char u = 's'; + + if (opt_units) { + u = tolower(opt_units[0]); + } + + switch(u) { + case 's': fmt_setunits(units_statute); break; + case 'm': fmt_setunits(units_metric); break; + default: fatal("Units argument '%s' should be 's' for statute units or 'm' for metric.", opt_units); break; + } + /* + * Reduce race conditions with network read link. + */ ofd = xfopen(fname, "w", MYNAME); } -void +/* + * The magic here is to try to ensure that posnfilename is atomically + * updated. + */ +static void +kml_wr_position_init(const char *fname) +{ + posnfilename = fname;; + posnfilenametmp = xstrappend(xstrdup(fname), "-"); + realtime_positioning = 1; + + /* + * 30% of our output file is whitespace. Since parse time + * matters in this mode, turn the pretty formatting off. + */ + do_indentation = 0; + kml_wr_init(posnfilenametmp); + + max_position_points = atoi(opt_max_position_points); +} + +static void kml_wr_deinit(void) { fclose(ofd); + + if (posnfilenametmp) { +#if __WIN32__ + /* + * This is gross. + * Windows does not offer an atomic rename; we must + * explictly remove the destination here which exposes + * a window where a polled reader of this file could find + * the file to be missing. Windows readers will simply + * have to retry on this case. + */ + unlink(posnfilename); +#endif + rename(posnfilenametmp, posnfilename); + xfree(posnfilenametmp); + posnfilenametmp = NULL; + } + ofd = NULL; +} + +/* + * Indent is a direction to change indention level. + * If positive, increase one level after printing this line. + * If zero, just print this line at the current indent leve. + * If negative, descrease the indent level. + */ +static void +kml_write_xml(int indent, const char *fmt, ...) +{ + va_list args; + int i; + va_start(args, fmt); + + if (indent < 0) indent_level--; + + if (fmt[1] != '!' && do_indentation) { + for (i = 0; i < indent_level; i++) { + fputs(" ", ofd); + } + } + + vfprintf(ofd, fmt, args); + + if (indent > 0) indent_level++; + + va_end(args); +} + +/* + * Write an optional tag with a value that may need to be entity escaped. + * Never changes indention leve, but does honour it. + */ +static void +kml_write_xmle(const char *tag, const char *v) +{ + int i; + if (v && *v) { + char *tmp_ent = xml_entitize(v); + for (i = 0; i < indent_level; i++) { + fputs(" ", ofd); + } + fprintf(ofd, "<%s>%s\n",tag, tmp_ent, tag); + xfree(tmp_ent); + } } -static void kml_write_bitmap_style(const char *style, int bitmap, - int x, int y, int width, int height) +#define hovertag(h) h ? 'h' : 'n' +static void kml_write_bitmap_style_(const char *style, const char * bitmap, + int highlighted) { - fprintf(ofd, "\n"); + kml_write_xml(0,"\n", + highlighted ? "Highlighted" : "Normal", style); + kml_write_xml(1, "\n"); } +/* A wrapper for the above function to emit both a highlighted + * and non-highlighted version of the style to allow the icons + * to magnify slightly on a rollover. + */ +static void kml_write_bitmap_style(const char *style, const char *bitmap) +{ + kml_write_bitmap_style_(style, bitmap, 0); + kml_write_bitmap_style_(style, bitmap, 1); + + kml_write_xml(1, "\n", style); + kml_write_xml(1, "\n"); + kml_write_xml(0, "normal\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(0)); + kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "highlight\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(1)); + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); +} static void kml_output_timestamp(const waypoint *waypointp) { + char time_string[64]; if (waypointp->creation_time) { - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t "); - xml_write_time(ofd, waypointp->creation_time, "timePosition"); - fprintf(ofd, "\t \n"); + xml_fill_in_time(time_string, waypointp->creation_time, XML_LONG_TIME); + if (time_string[0]) { + kml_write_xml(0, "%s\n", + time_string); + } } } +/* + * Output the track summary. + */ +static +void kml_output_trkdescription(const route_head *header, computed_trkdata *td) +{ + char *max_alt_units; + double max_alt; + char *min_alt_units; + double min_alt; + char *distance_units; + double distance; + + if (!td || !trackdata) { + return; + } + + max_alt = fmt_distance(td->max_alt, &max_alt_units); + min_alt = fmt_distance(td->min_alt, &min_alt_units); + distance = fmt_distance(td->distance_meters, &distance_units); + + kml_write_xml(0, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(1, "\n"); + + if (header->rte_desc) { + TD("Description %s", header->rte_desc); + } + TD2("Distance %.1f %s", distance, distance_units); + if (min_alt != unknown_alt) { + TD2("Min Alt %.1f %s", min_alt, min_alt_units); + } + if (max_alt != unknown_alt) { + TD2("Max Alt %.1f %s", max_alt, max_alt_units); + } + if (td->min_spd) { + char *spd_units; + double spd = fmt_speed(td->min_spd, &spd_units); + TD2("Min Speed %.1f %s", spd, spd_units); + } + if (td->max_spd) { + char *spd_units; + double spd = fmt_speed(td->max_spd, &spd_units); + TD2("Max Speed %.1f %s", spd, spd_units); + } + if (td->avg_hrt) { + TD("Avg Heart Rate %.1f bpm", td->avg_hrt); + } + if (td->min_hrt < td->max_hrt) { + TD("Min Heart Rate %d bpm", td->min_hrt); + } + if (td->max_hrt) { + TD("Max Heart Rate %d bpm", td->max_hrt); + } + if (td->avg_cad) { + TD("Avg Cadence %.1f rpm", td->avg_cad); + } + if (td->max_cad) { + TD("Max Cadence %d rpm", td->max_cad); + } -static void kml_output_header(const route_head *header) + kml_write_xml(-1, "

%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname); + cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], 1); + fprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn); + xfree (cout); + if (wpt->altitude != unknown_alt) + fprintf (file_out, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) ); fprintf (file_out, "
\n"); - if (strcmp(wpt->description, wpt->shortname)) { if (wpt->url) { char *d = html_entitize(wpt->description); - fprintf(file_out, "%s\n", wpt->url, d); + fprintf(file_out, "%s", wpt->url, d); xfree(d); } else { - fprintf(file_out, "%s\n", wpt->description); + fprintf(file_out, "%s", wpt->description); + } + if (wpt->gc_data.placer) { + fprintf(file_out, " by %s", wpt->gc_data.placer); } - } + fprintf(file_out, "

"); if (wpt->gc_data.terr) { - if (wpt->gc_data.desc_short.utfstring) { - char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_short.utfstring); - fprintf (file_out, "

%s

\n", tmpstr ); - xfree( tmpstr ); - } - if (wpt->gc_data.desc_long.utfstring) { - char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_long.utfstring); - fprintf (file_out, "

%s

\n", tmpstr ); - xfree( tmpstr ); - } - if (wpt->gc_data.hint) { - char *hint = NULL; - if ( encrypt ) - hint = rot13( wpt->gc_data.hint ); - else - hint = xstrdup( wpt->gc_data.hint ); - fprintf (file_out, "

Hint: %s

\n", hint); - xfree( hint ); - } + fprintf (file_out, "

%d%s / %d%s
\n", + (int)(wpt->gc_data.diff / 10), (wpt->gc_data.diff%10)?"½":"", + (int)(wpt->gc_data.terr / 10), (wpt->gc_data.terr%10)?"½":"" ); + fprintf(file_out, "%s / %s

", + gs_get_cachetype(wpt->gc_data.type), + gs_get_container(wpt->gc_data.container)); + } + fprintf(file_out, "
"); + if (wpt->gc_data.desc_short.utfstring) { + char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_short.utfstring); + fprintf (file_out, "

%s

\n", tmpstr ); + xfree( tmpstr ); + } + if (wpt->gc_data.desc_long.utfstring) { + char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_long.utfstring); + fprintf (file_out, "

%s

\n", tmpstr ); + xfree( tmpstr ); + } + if (wpt->gc_data.hint) { + char *hint = NULL; + if ( html_encrypt ) + hint = rot13( wpt->gc_data.hint ); + else + hint = xstrdup( wpt->gc_data.hint ); + fprintf (file_out, "

Hint: %s

\n", hint); + xfree( hint ); } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { - fprintf (file_out, "

%s

\n", wpt->notes); + fprintf (file_out, "

%s

\n", wpt->notes); } fs_gpx = NULL; @@ -141,17 +159,17 @@ html_disp(const waypoint *wpt) while ( curlog ) { time_t logtime = 0; struct tm *logtm = NULL; - fprintf( file_out, "

\n" ); + fprintf( file_out, "

\n" ); logpart = xml_findfirst( curlog, "groundspeak:type" ); if ( logpart ) { - fprintf( file_out, "%s by ", logpart->cdata ); + fprintf( file_out, "%s by ", logpart->cdata ); } logpart = xml_findfirst( curlog, "groundspeak:finder" ); if ( logpart ) { char *f = html_entitize( logpart->cdata ); - fprintf( file_out, "%s on ", f ); + fprintf( file_out, "%s on ", f ); xfree( f ); } @@ -161,11 +179,10 @@ html_disp(const waypoint *wpt) logtm = localtime( &logtime ); if ( logtm ) { fprintf( file_out, - "%2.2d/%2.2d/%4.4d
\n", + "%04d-%02d-%02d
\n", + logtm->tm_year+1900, logtm->tm_mon+1, - logtm->tm_mday, - logtm->tm_year+1900 - ); + logtm->tm_mday ); } } @@ -173,9 +190,7 @@ html_disp(const waypoint *wpt) if ( logpart ) { char *coordstr = NULL; float lat = 0; - int latdeg = 0; float lon = 0; - int londeg = 0; coordstr = xml_attribute( logpart, "lat" ); if ( coordstr ) { lat = atof( coordstr ); @@ -184,15 +199,11 @@ html_disp(const waypoint *wpt) if ( coordstr ) { lon = atof( coordstr ); } - latdeg = abs(lat); - londeg = abs(lon); - + coordstr = pretty_deg_format(lat, lon, degformat[2], 1); fprintf( file_out, - "%c %d° %.3f' %c %d° %.3f'
\n", - - lat < 0 ? 'S' : 'N', latdeg, 60.0 * (fabs(lat) - latdeg), - lon < 0 ? 'W' : 'E', londeg, 60.0 * (fabs(lon) - londeg) - ); + "%s
\n", + coordstr ); + xfree(coordstr); } logpart = xml_findfirst( curlog, "groundspeak:text" ); @@ -204,7 +215,7 @@ html_disp(const waypoint *wpt) encstr = xml_attribute( logpart, "encoded" ); encoded = (encstr[0] != 'F'); - if ( encrypt && encoded ) { + if ( html_encrypt && encoded ) { s = rot13( logpart->cdata ); } else { @@ -244,10 +255,16 @@ data_write(void) fprintf(file_out, "\n"); fprintf(file_out, "\n"); fprintf(file_out, "\n"); + fprintf(file_out, " \n"); + fprintf(file_out, " \n", gpsbabel_version); fprintf(file_out, " GPSBabel HTML Output\n"); - fprintf(file_out, " \n"); if (stylesheet) fprintf(file_out, " \n", stylesheet); + else { + fprintf(file_out, " \n"); + } fprintf(file_out, "\n"); fprintf(file_out, "\n"); @@ -273,5 +290,6 @@ ff_vecs_t html_vecs = { NULL, data_write, NULL, - html_args + html_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/igc.c b/igc.c index 95c7d41ac..f51397550 100644 --- a/igc.c +++ b/igc.c @@ -26,8 +26,7 @@ #include "defs.h" #include -static FILE *file_in; -static FILE *file_out; +static gbfile *file_in, *file_out; static char manufacturer[4]; static const route_head *head; static char *timeadj = NULL; @@ -88,42 +87,37 @@ static unsigned char coords_match(double lat1, double lon1, double lat2, double * @param rec Caller allocated storage for the record. At least MAXRECLEN chars must be allocated. * @return the record type. rec_none on EOF, rec_bad on fgets() or parse error. */ -static igc_rec_type_t get_record(char *rec) +static igc_rec_type_t get_record(char **rec) { size_t len; + char *c; - if (fgets(rec, MAXRECLEN, file_in) == NULL) { - if (feof(file_in)) { - return rec_none; - } else { - warning(MYNAME " fgets(): %s\n", strerror(errno)); - return rec_bad; - } - } - len = strlen(rec); - if (len < 3 || rec[0] < 'A' || rec[0] > 'Z') { - warning(MYNAME " bad input record: '%s'\n", rec); + *rec = c = gbfgetstr(file_in); + if (c == NULL) return rec_none; + + len = strlen(c); + if (len < 3 || c[0] < 'A' || c[0] > 'Z') { + warning(MYNAME " bad input record: '%s'\n", c); return rec_bad; } - rec[len - 2] = '\0'; - return (igc_rec_type_t) rec[0]; + return (igc_rec_type_t) c[0]; } static void rd_init(const char *fname) { - char ibuf[MAXRECLEN]; + char *ibuf; - file_in = xfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "r", MYNAME); // File must begin with a manufacturer/ID record - if (get_record(ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { + if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { fatal(MYNAME ": %s is not an IGC file\n", fname); } } static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); } /** @@ -240,7 +234,7 @@ static void igc_task_rec(const char *rec) static void data_read(void) { - char ibuf[MAXRECLEN]; + char *ibuf; igc_rec_type_t rec_type; unsigned int hours, mins, secs; unsigned int lat_deg, lat_min, lat_frac; @@ -266,7 +260,7 @@ static void data_read(void) strcpy(trk_desc, HDRMAGIC HDRDELIM); while (1) { - rec_type = get_record(ibuf); + rec_type = get_record(&ibuf); switch (rec_type) { case rec_manuf_id: // Manufacturer/ID record already found in rd_init(). @@ -358,7 +352,7 @@ static void data_read(void) } else { pres_wpt->altitude = unknown_alt; } - route_add_wpt(pres_head, pres_wpt); + track_add_wpt(pres_head, pres_wpt); // Add the same waypoint with GNSS altitude to the second // track @@ -370,7 +364,7 @@ static void data_read(void) } else { gnss_wpt->altitude = unknown_alt; } - route_add_wpt(gnss_head, gnss_wpt); + track_add_wpt(gnss_head, gnss_wpt); break; case rec_task: @@ -572,13 +566,13 @@ static void wr_header(void) if (NULL == (tm = gmtime(&date))) { fatal(MYNAME ": Bad track timestamp\n"); } - xfprintf(MYNAME, file_out, "HFDTE%s\r\n", date2str(tm)); + gbfprintf(file_out, "HFDTE%s\r\n", date2str(tm)); // Other header data may have been stored in track description if (track && track->rte_desc && strncmp(track->rte_desc, HDRMAGIC, strlen(HDRMAGIC)) == 0) { for (str = strtok(track->rte_desc + strlen(HDRMAGIC) + strlen(HDRDELIM), HDRDELIM); str; str = strtok(NULL, HDRDELIM)) { - xfprintf(MYNAME, file_out, "%s\r\n", str); + gbfprintf(file_out, "%s\r\n", str); } } else { // IGC header info not found so synthesise it. @@ -588,7 +582,7 @@ static void wr_header(void) if (NULL != (wpt = find_waypt_by_name("PILOT")) && wpt->description) { str = wpt->description; } - xfprintf(MYNAME, file_out, "HFPLTPILOT:%s\r\n", str); + gbfprintf(file_out, "HFPLTPILOT:%s\r\n", str); } } @@ -598,7 +592,7 @@ static void wr_header(void) static void wr_task_wpt_name(const waypoint * wpt, const char *alt_name) { - xfprintf(MYNAME, file_out, "C%s%s\r\n", latlon2str(wpt), + gbfprintf(file_out, "C%s%s\r\n", latlon2str(wpt), wpt->description ? wpt->description : wpt->shortname ? wpt->shortname : alt_name); } @@ -640,7 +634,7 @@ static void wr_task_hdr(const route_head * rte) sscanf(rte->rte_desc, DATEMAGIC "%6[0-9]: %s", flight_date, task_desc); } - xfprintf(MYNAME, file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), + gbfprintf(file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), tod2str(tm), flight_date, task_num++, num_tps, task_desc); if (!have_takeoff) { @@ -685,7 +679,7 @@ static void wr_fix_record(const waypoint * wpt, int pres_alt, int gnss_alt) if (unknown_alt == gnss_alt) { gnss_alt = 0; } - xfprintf(MYNAME, file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, + gbfprintf(file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, tm->tm_min, tm->tm_sec, latlon2str(wpt), pres_alt, gnss_alt); } @@ -866,30 +860,30 @@ static void wr_track(void) static void wr_init(const char *fname) { - file_out = xfopen(fname, "wb", MYNAME); + file_out = gbfopen(fname, "wb", MYNAME); } static void wr_deinit(void) { - fclose(file_out); + gbfclose(file_out); } static void data_write(void) { - xfputs(MYNAME, "AXXXZZZGPSBabel\r\n", file_out); + gbfputs("AXXXZZZGPSBabel\r\n", file_out); wr_header(); wr_tasks(); wr_track(); - xfprintf(MYNAME, file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); - xfputs(MYNAME, "GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); + gbfprintf(file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); + gbfputs("GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); } static arglist_t igc_args[] = { {"timeadj", &timeadj, "(integer sec or 'auto') Barograph to GPS time diff", - NULL, ARGTYPE_STRING}, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; ff_vecs_t igc_vecs = { @@ -902,5 +896,6 @@ ff_vecs_t igc_vecs = { data_read, data_write, NULL, - igc_args + igc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/ignrando.c b/ignrando.c new file mode 100644 index 000000000..98b449bfa --- /dev/null +++ b/ignrando.c @@ -0,0 +1,318 @@ +/* + + Support for IGN Rando track files, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include +#include +#include +#include + +#include "defs.h" +#include "xmlgeneric.h" + +#if HAVE_LIBEXPAT +#include +#endif + +#define MYNAME "IGNRando" + +static FILE *fout; + +static route_head *track; +static waypoint *wpt; +static int track_index; /* index of track we'll write */ +static int track_num; /* current index of track within track_disp_all */ + +static int xmlpoints; + +/* options */ +static char *index_opt = NULL; + +static arglist_t ignr_args[] = +{ + {"index", &index_opt, "Index of track to write (if more the one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + +#if ! HAVE_LIBEXPAT + +static void +ignr_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded \"" MYNAME "\" input support because expat was not installed.\n"); +} + +static void +ignr_read(void) +{ +} + +static void +ignr_rd_deinit(void) +{ +} + +#else + + +static xg_callback ignr_start; +static xg_callback ignr_nb_etapes, ignr_descr; +static xg_callback ignr_etape_begin, ignr_etape_end; +static xg_callback ignr_etape_pos, ignr_etape_alt; + +static +xg_tag_mapping ignr_xml_map[] = +{ + { ignr_start, cb_start, "/RANDONNEE" }, + { ignr_nb_etapes, cb_cdata, "/RANDONNEE/INFORMATIONS/NB_ETAPES" }, + { ignr_descr, cb_cdata, "/RANDONNEE/INFORMATIONS/DESCRIPTION" }, + { ignr_etape_begin, cb_start, "/RANDONNEE/ETAPE" }, + { ignr_etape_end, cb_end, "/RANDONNEE/ETAPE" }, + { ignr_etape_pos, cb_cdata, "/RANDONNEE/ETAPE/POSITION" }, + { ignr_etape_alt, cb_cdata, "/RANDONNEE/ETAPE/ALTITUDE" }, + { NULL, 0, NULL } +}; + +static void +ignr_xml_error(int condition) +{ + if (condition != 0) + fatal(MYNAME ": Error in XML structure!\n"); +} + +/* xmlgeneric callbacks */ + +static xg_callback ignr_start; +static xg_callback ignr_nb_etapes, ignr_descr; +static xg_callback ignr_etape_begin, ignr_etape_end; + +static void +ignr_start(const char *args, const char **attrv) +{ + ignr_xml_error((track != NULL)); + + track = route_head_alloc(); + track_add_head(track); +} + +static void +ignr_nb_etapes(const char *args, const char **attrv) +{ + xmlpoints = atoi(args); +} + +static void +ignr_descr(const char *args, const char **attrv) +{ + ignr_xml_error((track == NULL)); + + if ((args != NULL) && (strlen(args) > 0)) + track->rte_desc = xstrdup(args); +} + +static void +ignr_etape_begin(const char *args, const char **attrv) +{ + ignr_xml_error((wpt != NULL)); + + wpt = waypt_new(); +} + +static void +ignr_etape_end(const char *args, const char **attrv) +{ + ignr_xml_error((track == NULL) || (wpt == NULL)); + + track_add_wpt(track, wpt); + wpt = NULL; +} + +static void +ignr_etape_pos(const char *args, const char **attrv) +{ + ignr_xml_error((wpt == NULL) || (args == NULL)); + + if (2 != sscanf(args, "%lf,%lf", &wpt->latitude, &wpt->longitude)) + fatal(MYNAME ": Invalid coordinates \"%s\"!\n", args); +} + +static void +ignr_etape_alt(const char *args, const char **attrv) +{ + ignr_xml_error((wpt == NULL)); + if (args == NULL) return; + + if (1 != sscanf(args, "%lf", &wpt->altitude)) + fatal(MYNAME ": Invalid altitude \"%s\"!\n", args); +} + +/* callbacks registered in ignr_vecs */ + +static void +ignr_rd_init(const char *fname) +{ + xml_init(fname, ignr_xml_map, NULL); + wpt = NULL; + track = NULL; +} + +static void +ignr_rd_deinit(void) +{ + xml_deinit(); +} + +static void +ignr_read(void) +{ + xml_read(); +} + +#endif + +/* write support */ + +static void +ignr_fprintf(FILE *f, const char *fmt, ...) +{ + char buff[256]; + char *temp = buff; + va_list args; + int i; + + va_start(args, fmt); + + i = vsnprintf(buff, sizeof(buff), fmt, args); + if (i >= (int) sizeof(buff)) + { + temp = xmalloc(i + 1); + i = vsnprintf(temp, i + 1, fmt, args); + } + if (i < 0) + { + fatal(MYNAME ": error in vsnprintf.\n"); + } + else if (i > 0) + { + char eol = temp[i - 1]; + if (eol == '\n') i--; + fwrite(temp, 1, i, f); + if (eol == '\n') fprintf(f, "\r\n"); + } + + if (temp != buff) xfree(temp); + va_end(args); +} + +/* callbacks registered in ignr_vecs */ + +static void +ignr_rw_init(const char *fname) +{ + fout = xfopen(fname, "wb", MYNAME); +} + +static void +ignr_rw_deinit(void) +{ + fclose(fout); +} + +static void +ignr_write_track_hdr(const route_head *track) +{ + track_num++; + + if (track_num != track_index) return; + + ignr_fprintf(fout, "\t\n"); + ignr_fprintf(fout, "\t\t%d\n", track->rte_waypt_ct); + if (track->rte_desc != NULL) + ignr_fprintf(fout, "\t\t%s\n", track->rte_desc); + ignr_fprintf(fout, "\t\n"); +} + +static void +ignr_write_track_trl(const route_head *track) +{ +} + +static void +ignr_write_waypt(const waypoint *wpt) +{ + if (track_num != track_index) return; + + ignr_fprintf(fout, "\t\n"); + ignr_fprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); + if (wpt->altitude != unknown_alt) + ignr_fprintf(fout, "\t\t%3.6f\n", wpt->altitude); + ignr_fprintf(fout, "\t\n"); +} + +static void +ignr_write(void) +{ + time_t now; + struct tm tm; + char buff[32]; + + if (index_opt != NULL) + { + track_index = atoi(index_opt); + if ((track_index < 1) || (track_index > (int) track_count())) + fatal(MYNAME ": Invalid track index %d (we have currently %d track(s))!\n", + track_index, track_count()); + } + else + track_index = 1; + track_num = 0; + + now = current_time(); + tm = *localtime(&now); + + ignr_fprintf(fout, "\n"); + ignr_fprintf(fout, "\n"); + ignr_fprintf(fout, "\t\n"); + ignr_fprintf(fout, "\t\t1.1\n"); + ignr_fprintf(fout, "\t\tIHA03AA\n"); + + strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); + ignr_fprintf(fout, "\t\t%s\n", buff); + strftime(buff, sizeof(buff), "%H:%M:%S", &tm); + ignr_fprintf(fout, "\t\t%s\n", buff); + + ignr_fprintf(fout, "\t\n"); + track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); + ignr_fprintf(fout, "\n"); +} + +ff_vecs_t ignr_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + ignr_rd_init, + ignr_rw_init, + ignr_rd_deinit, + ignr_rw_deinit, + ignr_read, + ignr_write, + NULL, + ignr_args, + CET_CHARSET_MS_ANSI, 1 +}; diff --git a/inifile.c b/inifile.c new file mode 100644 index 000000000..8a9f57b60 --- /dev/null +++ b/inifile.c @@ -0,0 +1,351 @@ +/* + Library for inifile like data files. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include +#include +#include +#include + +#include "defs.h" +#include "inifile.h" + +#define MYNAME "inifile" + +typedef struct inifile_entry_s +{ + queue Q; + char *key; + char *val; +} inifile_entry_t; + +typedef struct inifile_section_s +{ + queue Q; + char *name; + int ientries; + queue entries; +} inifile_section_t; + +/* internal procedures */ + +#define START_BUFSIZE 257 +#define DELTA_BUFSIZE 128 + +#define GPSBABEL_INIFILE "gpsbabel.ini" + +static char * +find_gpsbabel_inifile(const char *path) /* can be empty or NULL */ +{ + FILE *test; + char *buff; + int len; + + if (path == NULL) return NULL; + + len = strlen(path); + buff = xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1); + strcpy(buff, path); + if (len > 0) { + char test = buff[len - 1]; +#ifdef __WIN32__ + if ((test != '\\') && (test != ':')) + strcat(buff, "\\"); +#else + if (test != '/') + strcat(buff, "/"); +#endif + } + strcat(buff, GPSBABEL_INIFILE); + test = fopen(buff, "rb"); + if (test) { + fclose(test); + return buff; + } + xfree(buff); + return NULL; +} + +static gbfile * +open_gpsbabel_inifile(void) +{ + char *name; + char *envstr; + gbfile *res = NULL; + + envstr = getenv("GPSBABELINI"); + if (envstr != NULL) { + FILE *test; + + test = fopen(envstr, "r"); + if (test != NULL) { + fclose(test); + return gbfopen(envstr, "r", "GPSBabel"); + } + warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n"); + return NULL; + } + name = find_gpsbabel_inifile(""); /* PWD */ + if (name == NULL) { +#ifdef __WIN32__ + name = find_gpsbabel_inifile(getenv("APPDATA")); + if (name == NULL) name = find_gpsbabel_inifile(getenv("WINDIR")); + if (name == NULL) name = find_gpsbabel_inifile(getenv("SYSTEMROOT")); +#else + if ((envstr = getenv("HOME")) != NULL) { + char *path; + + path = xmalloc(strlen(envstr) + 11); + strcpy(path, envstr); + strcat(path, "/.gpsbabel"); + name = find_gpsbabel_inifile(path); + xfree(path); + } + if (name == NULL) name = find_gpsbabel_inifile("/usr/local/etc"); + if (name == NULL) name = find_gpsbabel_inifile("/etc"); +#endif + } + if (name != NULL) { + res = gbfopen(name, "r", "GPSBabel"); + xfree(name); + } + return res; +} + +static void +inifile_load_file(gbfile *fin, inifile_t *inifile, const char *myname) +{ + char *buf; + inifile_section_t *sec = NULL; + + while ((buf = gbfgetstr(fin))) + { + char *cin = lrtrim(buf); + + if (*cin == '\0') continue; /* skip empty lines */ + if ((*cin == '#') || (*cin == ';')) continue; /* skip comments */ + + if (*cin == '[') + { + + char *cend = strchr(++cin, ']'); + + if (cend != NULL) + { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) + fatal("%s: invalid section header!\n", myname); + + sec = xcalloc(1, sizeof(*sec)); + + sec->name = xstrdup(cin); + QUEUE_INIT(&sec->entries); + ENQUEUE_TAIL(&inifile->secs, &sec->Q); + inifile->isecs++; + } + else + { + char *cx; + inifile_entry_t *entry; + + if (sec == NULL) + fatal("%s: missing section header!\n", myname); + + entry = xcalloc(1, sizeof(*entry)); + ENQUEUE_TAIL(&sec->entries, &entry->Q); + sec->ientries++; + + cx = strchr(cin, '='); + if (cx != NULL) + { + *cx = '\0'; + cin = lrtrim(cin); + } + + entry->key = xstrdup(cin); + + if (cx != NULL) + { + cx = lrtrim(++cx); + entry->val = xstrdup(cx); + } + else + entry->val = xstrdup(""); + } + } +} + +static char * +inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *key) +{ + queue *elem, *tmp; + + if (inifile == NULL) return NULL; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) + { + inifile_section_t *sec = (inifile_section_t *) elem; + + if (case_ignore_strcmp(sec->name, sec_name) == 0) + { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) + { + inifile_entry_t *entry = (inifile_entry_t *) elem; + + if (case_ignore_strcmp(entry->key, key) == 0) + { + return entry->val; + } + } + } + } + return NULL; +} + +/* public procedures */ + +/* + inifile_init: + reads inifile filename into memory + myname represents the calling module + + filename == NULL: try to open global gpsbabel.ini + */ +inifile_t * +inifile_init(const char *filename, const char *myname) +{ + inifile_t *result; + gbfile *fin = NULL; + + if (filename == NULL) { + fin = open_gpsbabel_inifile(); + if (fin == NULL) return NULL; + } + else fin = gbfopen(filename, "rb", myname); + + result = xcalloc(1, sizeof(*result)); + QUEUE_INIT(&result->secs); + inifile_load_file(fin, result, myname); + + gbfclose(fin); + return result; +} + +void +inifile_done(inifile_t *inifile) +{ + if (inifile == NULL) return; + + if (inifile->isecs > 0) + { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t *sec = (inifile_section_t *) elem; + + if (sec->ientries > 0) { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) { + inifile_entry_t *entry = (inifile_entry_t *) elem; + + if (entry->key) xfree(entry->key); + if (entry->val) xfree(entry->val); + dequeue(elem); + xfree(entry); + } + } + dequeue(elem); + if (sec->name) xfree(sec->name); + xfree(sec); + } + xfree(inifile); + } +} + +int +inifile_has_section(const inifile_t *inifile, const char *section) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) + { + inifile_section_t *sec = (inifile_section_t *) elem; + if (case_ignore_strcmp(sec->name, section) == 0) + return 1; + } + return 0; +} + +/* + inifile_readstr: + returns NULL if not found, otherwise a pointer to the value of key ... + all key values are valid entities until "inifile_done" + */ + +char * +inifile_readstr(const inifile_t *inifile, const char *section, const char *key) +{ + return inifile_find_value(inifile, section, key); +} + +/* + inifile_readint: + on success the value is stored into "*value" and "inifile_readint" returns 1, + otherwise inifile_readint returns 0 + */ + +int +inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value) +{ + char *str; + + str = inifile_find_value(inifile, section, key); + + if (str == NULL) { + return 0; + } + + if (value != NULL) { + *value = atoi(str); + } + return 1; +} + +/* + inifile_readint_def: + if found inifile_readint_def returns value of key, otherwise a default value "def" + */ + +int +inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def) +{ + int result; + + if (inifile_readint(inifile, section, key, &result) == 0) { + return def; + } + else { + return result; + } +} diff --git a/inifile.h b/inifile.h new file mode 100644 index 000000000..560727732 --- /dev/null +++ b/inifile.h @@ -0,0 +1,62 @@ +/* + Library for inifile like data files. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#ifndef HAVE_INIFILE_H +#define HAVE_INIFILE_H + +#include "defs.h" + +typedef struct inifile_s +{ + int isecs; /* number of sections */ + queue secs; /* sections */ +} inifile_t; + +/* + inifile_init: + reads inifile filename into memory + myname represents the calling module + */ +inifile_t * inifile_init(const char *filename, const char *myname); +void inifile_done(inifile_t *inifile); + +int inifile_has_section(const inifile_t *inifile, const char *section); + +/* + inifile_readstr: + returns NULL if not found, otherwise a pointer to the value of key ... + all key values are valid entities until "inifile_done" + */ +char *inifile_readstr(const inifile_t *inifile, const char *section, const char *key); + +/* + inifile_readint: + on success the value is stored into "*value" and "inifile_readint" returns 1, + otherwise inifile_readint returns 0 + */ +int inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value); + +/* + inifile_readint_def: + if found inifile_readint_def returns value of key, otherwise a default value "def" + */ +int inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def); + +#endif diff --git a/install-sh b/install-sh new file mode 100644 index 000000000..4d4a9519e --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/intdoc/SA2003_an1_dump.pl b/intdoc/SA2003_an1_dump.pl index 8bd7ce323..2145c48aa 100644 --- a/intdoc/SA2003_an1_dump.pl +++ b/intdoc/SA2003_an1_dump.pl @@ -31,8 +31,9 @@ sub decode { my $foo = shift; - my $deg = (0x80000000-$foo)/(0x800000); - sprintf( "%d %06.3f", $deg, 60*($deg-int($deg))); + my $intermed = 0x80000000-$foo; + my $deg = $intermed/(0x800000); + sprintf( "%8.8x %8.8x %d %06.3f", $foo, $intermed, $deg, 60*($deg-int($deg))); } @@ -80,12 +81,59 @@ while ( $bitmapcount ) { # This is a Windows ImageList stream. It actually includes the # 'BM' structures following in the stream, so we could be smarter # about how many we expect to find. (2 if bit 0 of ilflags is set, - # 1 otherwise. That bit is ILD_MASK.) For now, though, this works + # 1 otherwise. That bit is ILC_MASK.) For now, though, this works # just fine. Newer versions of the IL structure supposedly contain # more overlay indices, but SA always seems to use the 0x101 version. # Documentation on the stream format is hard to come by. I found - # mine in the form of the WINE project's reimplementation of comctl32. + # mine in the form of the WINE project's reimplementation of comctl32r: + + # http://cvs.winehq.org/cvsweb/wine/dlls/comctl32/#dirlist + # typedef struct _ILHEAD + # { + # USHORT usMagic; (RLP: this is 'IL', 0x4c49) + # USHORT usVersion; (RLP: SA likes 0x0101) + # WORD cCurImage; (RLP: image count) + # WORD cMaxImage; (RLP: max before grow) + # WORD cGrow; + # WORD cx; + # WORD cy; + # COLORREF bkcolor; (RLP: DWORD, 0x00bbggrr) + # WORD flags; (RLP: ILC_*; See below) + # SHORT ovls[4]; + # } ILHEAD; + + # #define ILC_MASK 0x00000001 + # #define ILC_COLOR 0x00000000 + # #define ILC_COLORDDB 0x000000FE + # #define ILC_COLOR4 0x00000004 + # #define ILC_COLOR8 0x00000008 + # #define ILC_COLOR16 0x00000010 + # #define ILC_COLOR24 0x00000018 + # #define ILC_COLOR32 0x00000020 + # See Windows SDK ImageList_Create for the meanings of these flags. + # Street Atlas appears to use ILC_COLOR32, both with and without ILC_MASK. + + # * The format is like this: + # * ILHEAD ilheadstruct; + # * + # * for the color image part: + # * BITMAPFILEHEADER bmfh; + # * BITMAPINFOHEADER bmih; + # * only if it has a palette: + # * RGBQUAD rgbs[nr_of_paletted_colors]; + # * + # * BYTE colorbits[imagesize]; + # * + # * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags: + # * BITMAPFILEHEADER bmfh_mask; + # * BITMAPINFOHEADER bmih_mask; + # * only if it has a palette (it usually does not): + # * RGBQUAD rgbs[nr_of_paletted_colors]; + # * + # * BYTE maskbits[imagesize]; + # * + # * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect. ($ilVersion, $ilCount, $ilMax, $ilGrow, $ilcx, $ilcy, $ilbkColor, $ilflags, $ilovl1, $ilovl2, $ilovl3, $ilovl4 ) = @@ -135,25 +183,28 @@ while ( $bitmapcount ) { ($magic, $wptcount) = shiftunpack( 'sl' ); -@types = qw(none marker line polygon text circle mapnote highlight unknown8 arc spline rectangle - unknown12 unknown13 road trail track waypoint); +@types = qw(none marker line polygon text circle mapnote highlight + unknown8 arc spline rectangle unknown12 unknown13 road + trail track waypoint photo); print( "$wptcount waypoints\n" ); while ( $wptcount ) { ($magic, $unk1, $lon, $lat, $type, $height, $width, $unk2, $unk3, $serial, $unk4, $create_zoom, $visible_zoom, $unk5, $circle_radius, $name, $font, - $guid, $fontcolor, $fontstyle, $fontsize, $unk6, $outlinecolor, $unk7, - $fillcolor, $unk8, $unk9 ) = + $guid, $fontcolor, $fontstyle, $fontsize, $outlineweight, $outlinecolor, + $outlineflags, $fillcolor, $unk6, $fillflags ) = shiftunpack( 'slllsllssssCCsds/a*s/a*a[16]lllllllll' ); # fontcolor is BGR (i.e. pure blue is 0xff00000, pure red is 0x0000ff) # fontstyle is 0x10-bold, 0x20-italic, 0x80-underline - # width/height are in pixels for mapnotes and represent the offset of the mapnote - # from the point (i.e. the dimensions of the tail.) + # width/height are in pixels for mapnotes and represent the offset of the + # mapnote from the point (i.e. the dimensions of the tail.) # width/height are in degrees times 0x800000 for rectangles + # circle_radius is in kilometers. + # Note that type appears to be shared with lines. # type desc # 1 marker (flag, dot, etc.) @@ -162,6 +213,9 @@ while ( $wptcount ) { # 6 mapnote # 11 rectangle # 17 waypoint + # 18 photo + + $lat = decode( $lat ); $lon = decode( $lon ); @@ -170,7 +224,9 @@ while ( $wptcount ) { $rect_width = $width/0x800000; printf ( "$magic -- %x %x %x %x %x %x %x %x %x -- $type $types[$type] $lat $lon %s $imagenames{$guid} '$name'\n", - $unk1, $unk2, $unk3, $unk4, $unk5, $unk6, $unk7, $unk8, $unk9, decodeGuid( $guid ) ); + $unk1, $unk2, $unk3, $unk4, $unk5, $unk6, decodeGuid( $guid ) ); + + printf (" %d height %d width %x fill %x outline %x fillstyle font %s\n", $height, $width, $fillcolor, $outlinecolor, $fillflags, $font); $wptcount--; } diff --git a/intdoc/SA2003_annotations.txt b/intdoc/SA2003_annotations.txt index 6cea4454d..2a6bd437a 100644 --- a/intdoc/SA2003_annotations.txt +++ b/intdoc/SA2003_annotations.txt @@ -32,7 +32,7 @@ I've also added notes to indicate where SA 2005 puts extra data -- end of routefile header -- - 03 00 00 00 count + 03 00 00 00 count of control points 01 00 type? 64 00 00 00 size diff --git a/intdoc/an1_road_types.txt b/intdoc/an1_road_types.txt new file mode 100644 index 000000000..fe3cb23b6 --- /dev/null +++ b/intdoc/an1_road_types.txt @@ -0,0 +1,52 @@ + +04xx Limited Access +08xx Primary +0Cxx Secondary +10xx Local Road + +Axes: + Toll/Limited/Primary/Secondary/Connecting/Local/- + Interstate/US/State/County/Farm/Indian/Urban/Forest/Ranch/Ferry/Exit/Minor/- + Unimproved/Under Construction/Approximation/- + +1107 .... + +0410 Primary Limited Access Limited - - +0420 Primary Limited Access Toll Toll - - +0430 Interstate Limited Interstate - +0440 Interstate Toll Toll Interstate - +0450 Interstate Under Construction Limited Interstate Const +0460 State Route Primary Limited Access Limited State - +0470 State Route Toll Toll State - +0480 US Route Primary Limited Access Limited US - +0490 US Route Toll Toll US - + +0810 Primary Non Limited Access Primary - - +0820 Interstate Business Route Primary Interstate - +0830 Primary Under Construction Primary - Const +0840 State Route - State - +0850 State Route Under Construction - State Const +0860 State Route Primary Primary State - +0870 US Route Primary US - +0880 US Route Under Construction Primary US Const + +0C10 Secondary State Secondary State - +0C20 Secondary Secondary - - +0C30 Connecting Road Connecting - - +0C40 County Route Connecting Road Connecting County - +0C50 Farm Route Connecting Road Connecting Farm - +0C60 Indian Route Connecting Road Connecting Indian - +0C70 Urban Connecting Road Connecting Urban - +0C80 Forest Connecting Road Connecting Forest - +0C90 Ranch Route Connecting Road Connecting Ranch - +0CA0 Ferry Crossing Connecting Road Connecting Ferry - +0CB0 Exit COnnecting Road Connecting Exit - +0CC0 Minor Connecting Road Connecting Minor - +0CD0 Unimproved Connecting Road Connecting - Unimproved +0CE0 Forest Secondary Road Secondary Forest - + +1010 Local or Rural Road Local - - +1020 Local Road Approximation Local - Approx +1030 Ferry Crossing Local Road Local Ferry - +1040 Unimproved Local Road Local - Unimproved + diff --git a/intdoc/jeeps-device.odg b/intdoc/jeeps-device.odg new file mode 100644 index 0000000000000000000000000000000000000000..c14bc30b72066cd772a5516a17cfac2048826206 GIT binary patch literal 9852 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 literal 0 HcmV?d00001 diff --git a/internal_styles.c b/internal_styles.c index 269b02537..34b1caf1c 100644 --- a/internal_styles.c +++ b/internal_styles.c @@ -1,6 +1,8 @@ /* This file is machine-generated from the contents of style/ */ /* by mkstyle.sh. Editing it by hand is an exeedingly bad idea. */ +#include "defs.h" +#if CSVFMTS_ENABLED static char arc[] = "# gpsbabel XCSV style file\n" "#\n" @@ -21,8 +23,31 @@ static char arc[] = "#\n" "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" "#\n" -"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" + +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +; +static char cambridge[] = +"DESCRIPTION Cambridge/Winpilot glider software\n" +"SHORTLEN 8\n" +"EXTENSION dat\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"IFIELD INDEX,\"1\",\"%d\"\n" +"IFIELD LAT_HUMAN_READABLE,\"\",\"%d:%06.3f%c\"\n" +"IFIELD LON_HUMAN_READABLE,\"\",\"%03d:%06.3f%c\"\n" +"IFIELD ALT_METERS,\"\",\"%3.0fM\"\n" +"IFIELD CONSTANT,\"\",\"T\"\n" +"IFIELD SHORTNAME,\"\",\"%s\"\n" +"IFIELD DESCRIPTION,\"\",\"%s\"\n" ; static char csv[] = "# gpsbabel XCSV style file\n" @@ -52,6 +77,54 @@ static char csv[] = "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" "OFIELD DESCRIPTION, \"\", \"%s\"\n" +; +static char cup[] = +"#\n" +"# (c) 2006, Robert Lipe, based on sample files by Krzysztof Wojtas\n" +"# Reference info: http://www.seeyou.ws/thankyou.php?fname=cup_format.pdf\n" +"#\n" + +"DESCRIPTION See You flight analysis data\n" +"SHORTLEN 8\n" +"EXTENSION cup\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS ,\"\n" +"PROLOGUE name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc\n" +"EPILOGUE -----Related Tasks-----\n" + + +"IFIELD SHORTNAME,\"\", \"\"%s\"\"\n" +"IFIELD SHORTNAME,\"\", \"%s\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD LAT_NMEA, \"%f\", \"%08.3f\", \"absolute\"\n" +"IFIELD LON_NMEA, \"%f\", \"%09.3f\", \"absolute\"\n" +"IFIELD ALT_METERS,\"\", \"%dm\"\n" +"IFIELD CONSTANT,\"\", \"1\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD CONSTANT,\"\", \"\"\n" +"IFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" + +"OFIELD SHORTNAME,\"\", \"\"%s\"\"\n" +"OFIELD SHORTNAME,\"\", \"%s\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD LAT_NMEA, \"%f\", \"%08.3f\", \"absolute\"\n" +"OFIELD LAT_DIR, \"\", \"%c\", \"no_delim_before\"\n" +"OFIELD LON_NMEA, \"%f\", \"%09.3f\", \"absolute\"\n" +"OFIELD LON_DIR, \"\", \"%c\", \"no_delim_before\"\n" +"OFIELD ALT_METERS,\"\", \"%3.1fm\"\n" +"OFIELD CONSTANT,\"\", \"1\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD CONSTANT,\"\", \"\"\n" +"OFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" + + ; static char custom[] = "# gpsbabel XCSV style file\n" @@ -80,7 +153,7 @@ static char custom[] = "#\n" "# INDIVIDUAL DATA FIELDS:\n" "#\n" -"IFIELD CONSTANT, \"\", \"CONSTANT\"\n" +"IFIELD CONSTANT, \"CONSTANT\", \"%s\"\n" "IFIELD INDEX, \"\", \"%d\"\n" "IFIELD LAT_DECIMAL, \"\", \"%f\"\n" "IFIELD LAT_DIR, \"\", \"%c\"\n" @@ -180,6 +253,129 @@ static char fugawi[] = "IFIELD GMT_TIME, \"\", \"%Y%m%d\"\n" "IFIELD HMSG_TIME, \"\", \"%02d%02d%02d\"\n" ; +static char garmin301[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Garmin 301 Position + Heartrate data\n" +"# Author: Jeff Kalikstein\n" +"# Date: 08/29/2005\n" +"#\n" + +"DESCRIPTION Garmin 301 Custom position and heartrate\n" + +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" +"#FORMAT_TYPE INTERNAL\n" + +"#\n" +"# HEADER STUFF:\n" +"#\n" +"PROLOGUE Garmin 301 data __FILE__ \n" +"PROLOGUE Timestamp,Latitude, Longitude, Altitude(ft), heart rate\n" +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD TIMET_TIME,\"\",\"%ld\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD ALT_FEET, \"\", \"%fF\"\n" +"IFIELD HEART_RATE,\"\",\" %d\" # beats per minute\n" + + +"# EPILOGUE: \n" +"#EPILOGUE Epilogue Line 1\n" +"#EPILOGUE Epilogue Line 2\n" +; +static char garmin_poi[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Garmin POI\n" +"# Author: Robert Lipe\n" +"# Date: 10/07/2005\n" +"# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204\n" +"#\n" +"DESCRIPTION Garmin POI database\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" +"SHORTLEN 24\n" +"# PROLOGUE Longitude,Latitude,Name, comment\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" + +"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" +"OFIELD SHORTNAME, \"\", \"%-.24s\"\n" +"OFIELD GEOCACHE_TYPE, \"\", \" %-.4s\", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_CONTAINER, \"\", \"/%-.4s \", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_DIFF, \"\", \"(%3.1f\", \"no_delim_before,optional\"\n" +"OFIELD GEOCACHE_TERR, \"\", \"/%3.1f)\", \"no_delim_before,optional\"\n" +"OFIELD DESCRIPTION, \"\", \"%-.50s\"\n" +; +static char geonet[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: GEOnet Names Server (GNS) (http://earth-info.nga.mil/gns/html/cntry_files.html)\n" +"# Author: Olaf Klein\n" +"# Date: 08/20/2002\n" +"#\n" + +"DESCRIPTION GEOnet Names Server (GNS)\n" +"EXTENSION txt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" + +"FIELD_DELIMITER TAB\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS TAB\n" +"ENCODING UTF-8\n" + +"PROLOGUE RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD IGNORE, \"\", \"%s\" # RC ( http://earth-info.nga.mil/gns/html/gis_contryfiles.html )\n" +"IFIELD IGNORE, \"\", \"%s\" # UFI\n" +"IFIELD IGNORE, \"\", \"%s\" # UNI\n" +"IFIELD LAT_DECIMAL, \"\", \"%03.7f\" # LAT\n" +"IFIELD LON_DECIMAL, \"\", \"%03.7f\" # LONG\n" +"IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" +"IFIELD IGNORE, \"\", \"%s\" # DMS_LONG\n" +"IFIELD IGNORE, \"\", \"%s\" # UTM\n" +"IFIELD IGNORE, \"\", \"%s\" # JOG\n" +"IFIELD IGNORE, \"\", \"%s\" # FC\n" +"IFIELD IGNORE, \"\", \"%s\" # DSG\n" +"IFIELD IGNORE, \"\", \"%s\" # PC\n" +"IFIELD IGNORE, \"\", \"%s\" # CC1\n" +"IFIELD IGNORE, \"\", \"%s\" # ADM1\n" +"IFIELD IGNORE, \"\", \"%s\" # ADM2\n" +"IFIELD IGNORE, \"\", \"%s\" # DIM\n" +"IFIELD IGNORE, \"\", \"%s\" # CC2\n" +"IFIELD IGNORE, \"\", \"%s\" # NT\n" +"IFIELD IGNORE, \"\", \"%s\" # LC\n" +"IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" +"IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" +"IFIELD SHORTNAME, \"\", \"%s\" # SHORT_NAME\n" +"IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME\n" +"IFIELD IGNORE, \"\", \"%s\" # FULL_NAME_ND\n" +"IFIELD IGNORE, \"\", \"%s\" # MOD_DATE\n" +; static char gpsdrive[] = "# gpsbabel XCSV style file\n" "#\n" @@ -238,10 +434,10 @@ static char gpsdrivetrack[] = "#\n" "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"OFIELD LAT_DECIMAL, \"\", \"%10.6f\"\n" -"OFIELD LON_DECIMAL, \"\", \"%10.6f\"\n" -"OFIELD ALT_METERS, \"\", \"%10.0f\"\n" -"OFIELD GMT_TIME, \"\", \"%a %b %d %T %Y\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%10.6f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%10.6f\"\n" +"IFIELD ALT_METERS, \"\", \"%10.0f\"\n" +"IFIELD GMT_TIME, \"\", \"%a %b %d %T %Y\"\n" ; static char gpsman[] = "# gpsbabel XCSV style file\n" @@ -279,6 +475,83 @@ static char gpsman[] = "# gpsman.c likes mkshort len = 8, whitespace = 0.\n" ; +static char ktf2[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kartex KTF 2.0 Degrees with decimals\n" +"# Author: Harald Nordius\n" +"# Date: 4/13 2006\n" +"#\n" +"# \n" +"DESCRIPTION Kartex 5 Track File\n" +"EXTENSION ktf\n" +"SHORTLEN 10\n" +"SHORTWHITE 1\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER CRNEWLINE\n" +"#\n" +"#\n" +"# FILE HEADER\n" +"#\n" +"PROLOGUE //Kartex Track File created by GPSBabel\n" +"PROLOGUE &KTF 2.0,sweref 99 lat long,0\n" +"#\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD CONSTANT, %, \"%s\"\n" +"IFIELD INDEX, \"\", \"%d\"\n" +"IFIELD LATLON_HUMAN_READABLE, \"\", \"%c%f°\"\n" +"IFIELD ALT_METERS, \"\", \"%.2f\"\n" +"IFIELD GMT_TIME, \"\", \"%Y-%m-%d %H:%M:%S\"\n" +"IFIELD IGNORE, \"\", \"%s\" #Empty field\n" +"IFIELD IGNORE, \"\", \"%s\" #Empty field\n" +"IFIELD CONSTANT, \"$\", \"%s\"\n" +; +static char kwf2[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Kartex KWF 2.0 Degrees with decimals\n" +"# Author: Harald Nordius\n" +"# Date: 12/08 2004\n" +"#\n" +"# \n" +"DESCRIPTION Kartex 5 Waypoint File\n" +"EXTENSION kwf\n" +"SHORTLEN 10\n" +"SHORTWHITE 1\n" +"#\n" +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER CRNEWLINE\n" +"ENCODING CP1252\n" +"#\n" +"#\n" +"# FILE HEADER\n" +"#\n" +"PROLOGUE //Kartex Waypoint File created by GPSBabel\n" +"PROLOGUE &KWF 2.0,sweref 99 lat long,0\n" +"#\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD CONSTANT, \\#, \"%s\"\n" +"IFIELD INDEX,\"\",\"%d\"\n" +"IFIELD SHORTNAME,\"\",\"%s\"\n" +"IFIELD LATLON_HUMAN_READABLE,\"\",\"%c%f°\"\n" +"IFIELD ALT_METERS,\"\",\"%.2f\"\n" +"IFIELD IGNORE, \"\",\"%s\" #Empty field\n" +"IFIELD IGNORE, \"\",\"%s\" #Empty field\n" +"IFIELD CONSTANT, \"0\",\"%s\" #Waypoint symbol code\n" +"IFIELD DESCRIPTION, \"\", \"%s\"\n" +"IFIELD CONSTANT, \"$\", \"%s\"\n" +; static char mapconverter[] = "# Format: Mapopolis.com Mapconverter\n" "# Author: Gary Paulson\n" @@ -336,15 +609,15 @@ static char mxf[] = "#\n" "FIELD_DELIMITER COMMASPACE\n" "RECORD_DELIMITER NEWLINE\n" -"BADCHARS \",\n" +"BADCHARS ,\"\n" "#\n" "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" "#\n" "IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" "IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" +"IFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" +"IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" "IFIELD IGNORE, \"\", \"%s\"\n" "IFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" "IFIELD CONSTANT, \"47\", \"%s\" # ICON\n" @@ -407,13 +680,13 @@ static char nima[] = static char openoffice[] = "# gpsbabel XCSV style file\n" "#\n" -"# Format: Tab delimitered csv useful for OpenOffice, Ploticus etc.\n" +"# Format: Tab delimited useful for OpenOffice, Ploticus etc.\n" "# Author: Tobias Minich\n" "# Date: 07/18/2005\n" "#\n" "#\n" -"DESCRIPTION Tab delimitered csv useful for OpenOffice, Ploticus etc.\n" +"DESCRIPTION Tab delimited fields useful for OpenOffice, Ploticus etc.\n" "# FILE LAYOUT DEFINITIIONS:\n" "#\n" @@ -468,7 +741,7 @@ static char s_and_t[] = "# GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache\n" "#\n" -"DESCRIPTION Microsoft Streets and Trips 2002-2005\n" +"DESCRIPTION Microsoft Streets and Trips 2002-2006\n" "EXTENSION txt\n" @@ -525,6 +798,40 @@ static char saplus[] = "IFIELD URL, \"\", \"%s\" # URL\n" "IFIELD IGNORE, \"\", \"\" # Holder for Geocache Type\n" +; +static char sportsim[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: Sportsim track files\n" +"# Author: Olaf Klein\n" +"# Date: 07/05/2006\n" +"#\n" +"DESCRIPTION Sportsim track files (part of zipped .ssz files) \n" +"EXTENSION txt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER SEMICOLON\n" +"RECORD_DELIMITER CRNEWLINE\n" +"BADCHARS TAB\n" + +"#\n" +"# FILE HEADER\n" +"#\n" +"PROLOGUE SportsimVersion:01\n" +"PROLOGUE \\#Sportsim TrackFile\n" + +"#\n" +"# INDIVIDUAL DATA FIELDS:\n" +"#\n" +"IFIELD INDEX, \"\", \"%05d\"\n" +"IFIELD CONSTANT, \"0\", \"%s\"\n" +"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" +"IFIELD LON_DECIMAL, \"\", \"%f\"\n" +"IFIELD ALT_FEET, \"\", \"%.f\"\n" +"IFIELD TIMET_TIME, \"\", \"%ld\"\n" +"IFIELD CONSTANT, \";\", \"%s\"\n" ; static char tabsep[] = "# gpsbabel XCSV style file\n" @@ -582,6 +889,45 @@ static char tabsep[] = "IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" "IFIELD GEOCACHE_PLACER,\"\",\"%s\"\n" "IFIELD YYYYMMDD_TIME,\"\",\"%ld\"\n" +; +static char xmap2006[] = +"# gpsbabel XCSV style file\n" +"#\n" +"# Format: DeLorme Xmap/Street Atlas Handheld 2006 Conduit\n" +"# Author: Pasha Phares\n" +"# Date: 5/5/2006\n" +"#\n" +"# Amazingly, 2006 won't read the \"COMMASPACE\" that we used in \n" +"# in Xmap prior to this and versions before 2006 won't read files\n" +"# separated by only a comma.\n" +"# \n" + +"DESCRIPTION DeLorme XMap/SAHH 2006 Native .TXT\n" +"EXTENSION txt\n" + +"#\n" +"# FILE LAYOUT DEFINITIIONS:\n" +"#\n" +"FIELD_DELIMITER COMMA\n" +"RECORD_DELIMITER NEWLINE\n" +"BADCHARS COMMA\n" + +"PROLOGUE BEGIN SYMBOL\n" +"EPILOGUE END\n" +"#\n" +"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" +"#\n" +"IFIELD LAT_HUMAN_READABLE, \"\", \"%.12g\"\n" +"IFIELD LON_HUMAN_READABLE, \"\", \"%.12g\"\n" +"IFIELD SHORTNAME, \"\", \"%s\"\n" + +"OFIELD LAT_DECIMAL, \"\", \"%.12g\"\n" +"OFIELD LON_DECIMAL, \"\", \"%.12g\"\n" +"OFIELD SHORTNAME, \"\", \"%s\"\n" + + + + ; static char xmap[] = "# gpsbabel XCSV style file\n" @@ -649,6 +995,9 @@ static char xmapwpt[] = "IFIELD IGNORE, \"\", \"%-.31s\"\n" "IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" ; -#include "defs.h" -style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap", xmap } , { "tabsep", tabsep } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "openoffice", openoffice } , { "nima", nima } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "fugawi", fugawi } , { "dna", dna } , { "custom", custom } , { "csv", csv } , { "arc", arc } , {0,0}}; -size_t nstyles = 17; +style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap", xmap } , { "xmap2006", xmap2006 } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "openoffice", openoffice } , { "nima", nima } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; +size_t nstyles = 26; +#else /* CSVFMTS_ENABLED */ +style_vecs_t style_list[] = {{0,0}}; +size_t nstyles = 0; +#endif /* CSVFMTS_ENABLED */ diff --git a/interpolate.c b/interpolate.c new file mode 100644 index 000000000..776513cc7 --- /dev/null +++ b/interpolate.c @@ -0,0 +1,194 @@ +/* + Interpolate filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED +#define MYNAME "Interpolate filter" + +static char *opt_interval = NULL; +int interval = 0; +static char *opt_dist = NULL; +double dist = 0; +static char *opt_route = NULL; + +static +arglist_t interpfilt_args[] = { + {"time", &opt_interval, "Time interval in seconds", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT, + "0", NULL }, + {"distance", &opt_dist, "Distance interval in miles or kilometers", + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING, + ARG_NOMINMAX }, + {"route", &opt_route, "Interpolate routes instead", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +void +interpfilt_process(void) +{ + queue *backuproute = NULL; + queue *elem, *tmp, *elem2, *tmp2; + route_head *rte_new; + int count = 0; + int first = 0; + double lat1 = 0, lon1 = 0; + int time1 = 0; + int timen; + double distn; + double curdist; + double rt1, rn1, rt2, rn2; + + if ( opt_route ) { + route_backup( &count, &backuproute ); + route_flush_all_routes(); + } + else { + track_backup( &count, &backuproute ); + route_flush_all_tracks(); + } + QUEUE_FOR_EACH( backuproute, elem, tmp ) + { + route_head *rte_old = (route_head *)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup( rte_old->rte_name ); + rte_new->rte_desc = xstrdup( rte_old->rte_desc ); + rte_new->fs = fs_chain_copy( rte_old->fs ); + rte_new->rte_num = rte_old->rte_num; + if ( opt_route ) { + route_add_head( rte_new ); + } + else { + track_add_head( rte_new ); + } + first = 1; + QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) + { + waypoint *wpt = (waypoint *)elem2; + if ( first ) { + first = 0; + } + else { + if ( opt_interval && + wpt->creation_time - time1 > interval ) { + for ( timen = time1+interval; + timen < wpt->creation_time; + timen += interval ) { + waypoint *wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = timen; + if (wpt_new->shortname) xfree(wpt_new->shortname); + if (wpt_new->description) xfree(wpt_new->description); + wpt_new->shortname = wpt_new->description = NULL; + linepart( lat1, lon1, + wpt->latitude, wpt->longitude, + (double)(timen-time1)/ + (double)(wpt->creation_time-time1), + &wpt_new->latitude, + &wpt_new->longitude ); + if (opt_route) + route_add_wpt( rte_new, wpt_new); + else + track_add_wpt( rte_new, wpt_new); + } + } + else if ( opt_dist ) { + rt1 = RAD(lat1); + rn1 = RAD(lon1); + rt2 = RAD(wpt->latitude); + rn2 = RAD(wpt->longitude); + curdist = gcdist( rt1, rn1, rt2, rn2 ); + curdist = radtomiles(curdist); + if ( curdist > dist ) { + for ( distn = dist; + distn < curdist; + distn += dist ) { + waypoint *wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = distn/curdist* + (wpt->creation_time - time1) + time1; + if (wpt_new->shortname) xfree(wpt_new->shortname); + if (wpt_new->description) xfree(wpt_new->description); + wpt_new->shortname = wpt_new->description = NULL; + linepart( lat1, lon1, + wpt->latitude, wpt->longitude, + distn/curdist, + &wpt_new->latitude, + &wpt_new->longitude ); + if (opt_route) + route_add_wpt( rte_new, wpt_new ); + else + track_add_wpt( rte_new, wpt_new); + } + } + } + } + if ( opt_route ) { + route_add_wpt( rte_new, waypt_dupe(wpt)); + } + else { + track_add_wpt( rte_new, waypt_dupe(wpt)); + } + + lat1 = wpt->latitude; + lon1 = wpt->longitude; + time1 = wpt->creation_time; + } + } + route_flush( backuproute ); + xfree( backuproute ); +} + +void +interpfilt_init(const char *args) { + + char *fm; + if ( opt_interval && opt_dist ) { + fatal( MYNAME ": Can't interpolate on both time and distance.\n"); + } + else if (opt_interval && opt_route ) { + fatal( MYNAME ": Can't interpolate routes on time.\n" ); + } + else if ( opt_interval ) { + interval = atoi(opt_interval); + } + else if ( opt_dist ) { + dist = strtod(opt_dist, &fm); + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to miles */ + dist *= .6214; + } + } + else { + fatal( MYNAME ": No interval specified.\n"); + } +} + +filter_vecs_t interpolatefilt_vecs = { + interpfilt_init, + interpfilt_process, + NULL, + NULL, + interpfilt_args +}; +#endif // FILTERS_ENABLED diff --git a/jeeps/Makefile.in b/jeeps/Makefile.in new file mode 100644 index 000000000..e69de29bb diff --git a/jeeps/garminusb.h b/jeeps/garminusb.h index 96acc9232..a05f9c15d 100644 --- a/jeeps/garminusb.h +++ b/jeeps/garminusb.h @@ -1,7 +1,7 @@ /* Definitions for Garmin USB protocol and implementation. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,14 +46,22 @@ union { * OS implementation. */ #define GUSB_MAX_UNITS 20 -struct { +struct garmin_unit_info { unsigned long serial_number; + unsigned long unit_id; + unsigned long unit_version; char *os_identifier; /* In case the OS has another name for it. */ char *product_identifier; /* From the hardware itself. */ } garmin_unit_info[GUSB_MAX_UNITS]; int gusb_cmd_send(const garmin_usb_packet *obuf, size_t sz); int gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz); -int gusb_open(const char *portname); -int gusb_close(const char *portname); -int gusb_init(void); +int gusb_init(const char *portname, gpsdevh **dh); +int gusb_close(gpsdevh *); + +/* + * New packet types in USB. + */ +#define GUSB_SESSION_START 5 /* We request units attention */ +#define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */ +#define GUSB_REQUEST_BULK 2 /* Unit requests we read from bulk pipe */ diff --git a/jeeps/gps.h b/jeeps/gps.h index b1de25c0e..e307b3aba 100644 --- a/jeeps/gps.h +++ b/jeeps/gps.h @@ -33,6 +33,7 @@ extern int32 gps_warning; extern int32 gps_error; extern int32 gps_user; extern int32 gps_show_bytes; +extern char gps_categories[16][17]; typedef struct GPS_SPacket @@ -86,9 +87,13 @@ typedef struct GPS_STrack time_t Time; /* Unix time */ float alt; /* Altitude */ float dpth; /* Depth */ - int32 heartrate; /* Heatrate as in Garmin 301 */ - int32 tnew; /* New track? */ - int32 ishdr; /* Track header? */ + float temperature; /* Temperature. Degrees Celsius. */ + int temperature_populated; /* True if above is valid. */ + unsigned char heartrate; /* Heartrate as in Garmin 301 */ + unsigned char cadence; /* Crank cadence as in Edge 305 */ + unsigned int tnew:1; /* New track? */ + unsigned int ishdr:1; /* Track header? */ + unsigned int no_latlon:1; /* True if no valid lat/lon found. */ int32 dspl; /* Display on map? */ int32 colour; /* Colour */ char trk_ident[256]; /* Track identifier */ @@ -130,6 +135,7 @@ typedef struct GPS_SWay int32 colour; char cc[2]; UC wpt_class; + UC alt_is_unknown; float alt; char city[24]; char state[2]; @@ -151,14 +157,32 @@ typedef struct GPS_SWay char rte_link_subclass[18]; char rte_link_ident[256]; - char Time_populated; /* 1 if true */ - time_t Time; /* Unix time */ + char time_populated; /* 1 if true */ + time_t time; /* Unix time */ + char temperature_populated; + float temperature; /* Degrees celsius. */ + uint16 category; + } GPS_OWay, *GPS_PWay; - - - -#include "gpsserial.h" +/* + * Forerunner Lap data. + */ +typedef struct GPS_SLap_Data { + time_t start_time; + uint32 total_time; /* Hundredths of a second */ + float total_distance; /* In meters */ + double begin_lat; + double begin_lon; + double end_lat; + double end_lon; + int16 calories; + UC track_index; +} GPS_OLap_Data, *GPS_PLap_Data; + +typedef int (*pcb_fn) (int, struct GPS_SWay **); + +#include "gpsdevice.h" #include "gpssend.h" #include "gpsread.h" #include "gpsutil.h" @@ -167,13 +191,10 @@ typedef struct GPS_SWay #include "gpscom.h" #include "gpsfmt.h" #include "gpsmath.h" -#include "gpsnmea.h" #include "gpsmem.h" #include "gpsrqst.h" #include "gpsinput.h" #include "gpsproj.h" -#include "gpsnmeafmt.h" -#include "gpsnmeaget.h" time_t gps_save_time; double gps_save_lat; diff --git a/jeeps/gpsapp.c b/jeeps/gpsapp.c index 4591c8286..104f535c7 100644 --- a/jeeps/gpsapp.c +++ b/jeeps/gpsapp.c @@ -4,6 +4,7 @@ ** @author Copyright (C) 1999 Alan Bleasby ** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2004, 2005, 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -28,6 +29,13 @@ #include #include +/* + * This violates the layering design, but is needed for device discovery. + * See the use of gps_is_usb and GPS_Packet_Read_usb below. + */ +#include "garminusb.h" +#include "gpsusbint.h" + #define XMIN(a,b) (a < b? a : b) static int32 GPS_A000(const char *port); @@ -72,6 +80,8 @@ static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len); static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len); static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len); +static void GPS_D120_Get(int n, char *data); + static void GPS_D200_Get(GPS_PWay *way, UC *s); static void GPS_D201_Get(GPS_PWay *way, UC *s); static void GPS_D202_Get(GPS_PWay *way, UC *s); @@ -88,10 +98,10 @@ static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len); static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len); static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len); -static int32 GPS_D500_Get(GPS_PAlmanac *alm, int32 entries, int32 fd); -static int32 GPS_D501_Get(GPS_PAlmanac *alm, int32 entries, int32 fd); -static int32 GPS_D550_Get(GPS_PAlmanac *alm, int32 entries, int32 fd); -static int32 GPS_D551_Get(GPS_PAlmanac *alm, int32 entries, int32 fd); +static int32 GPS_D500_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd); +static int32 GPS_D501_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd); +static int32 GPS_D550_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd); +static int32 GPS_D551_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd); static void GPS_D500_Send(UC *data, GPS_PAlmanac alm); static void GPS_D501_Send(UC *data, GPS_PAlmanac alm); static void GPS_D550_Send(UC *data, GPS_PAlmanac alm); @@ -146,17 +156,16 @@ int32 GPS_Init(const char *port) (void) GPS_Util_Little(); - /* - * Decide here if the portname refers to a USB device and set the - * global that's used as in inflection point for other decisions later. - */ - gps_is_usb = (0 == strncmp(port, "usb:", 4)); - ret = GPS_A000(port); if(ret<0) return ret; - if (gps_is_usb) return 1; gps_save_time = GPS_Command_Get_Time(port); - if(!gps_save_time) { + + /* + * Some units may be unable to return time, such as a C320 when in + * charging mode. Only consider it fatal if the unit returns an error, + * not just absence of returning a time. + */ + if(gps_save_time < 0) { return FRAMING_ERROR; } @@ -178,17 +187,16 @@ int32 GPS_Init(const char *port) ************************************************************************/ static int32 GPS_A000(const char *port) { - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int16 version; int16 id; - char tstr[256]; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; - if(!gps_is_usb && !GPS_Serial_Flush(fd)) + if(!GPS_Device_Flush(fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -208,20 +216,23 @@ static int32 GPS_A000(const char *port) version = GPS_Util_Get_Short((rec->data)+2); (void) strcpy(gps_save_string,(char *)rec->data+4); - GPS_User((char *)rec->data+4); - (void) sprintf(tstr,"ID:\t\t%d\n",id); gps_save_id = id; - GPS_User(tstr); gps_save_version = (double)((double)version/(double)100.); - (void) sprintf(tstr, - "Version:\t%.2f\n",gps_save_version); - GPS_User(tstr); + GPS_User("Unit:\t%s\nID:\t%d\nVersion:\t%.2f", + gps_save_string, gps_save_id, gps_save_version); +#if 0 gps_date_time_transfer = pA600; gps_date_time_type = pD600; /* All models so far */ gps_position_transfer = pA700; gps_position_type = pD700; /* All models so far */ +#else + gps_date_time_transfer = -1; + gps_date_time_type = -1; + gps_position_transfer = -1; + gps_position_type = -1; +#endif gps_pvt_transfer = -1; gps_pvt_type = -1; gps_prx_waypt_transfer = -1; @@ -231,7 +242,7 @@ static int32 GPS_A000(const char *port) gps_trk_hdr_type = -1; gps_rte_link_type = -1; - if(!GPS_Serial_Wait(fd)) + if(!GPS_Device_Wait(fd)) { GPS_Warning("A001 protocol not supported"); id = GPS_Protocol_Version_Change(id,version); @@ -240,30 +251,69 @@ static int32 GPS_A000(const char *port) } else { - int maxct = 3; + int i; /* * The unit may return more than one packet, so read and - * discard all but the product inquiry response. + * discard all but the product inquiry response. We have + * no way of knowing how many we'll get, so we have to keep + * reading until we incur a timeout. + * Worse still, the serial layer assumes a read timeout is a + * fatal error, while the USB layer (correctly) returns that error + * to the caller. So we call GPS_Device_Wait which spins into + * a delay/select for the serial system and a NOP for USB. + * + * Worse _yet_, this is the one place in all of Garmin Protocolsville + * where we don't know a priori how many packets will be sent in + * response. Since we want the lower levels of the USB handler + * to handle the ugliness of the "return to interrupt" packets, we + * reach behind that automation here and hand that ourselves. */ - while (maxct--) { - (void) GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); - if (rec->type == 0xfd) { - GPS_A001(rec); - break; + for (i = 0; i < 25; i++) { + rec->type = 0; + + if (gps_is_usb) { + GPS_Packet_Read_usb(fd, &rec, 0); + } else { + if(!GPS_Device_Wait(fd)) + goto carry_on; + + if (GPS_Packet_Read(fd, &rec) <= 0) { + goto carry_on; } + + GPS_Send_Ack(fd, &tra, &rec); + } + + if (rec->type == 0xfd) { + GPS_A001(rec); + goto carry_on; + } + + /* + * If a 296 has previously been interrupted, it's going to + * ignore the session request (grrrr) and continue to send + * us left over packets. So if we see anything that isn't + * part of our A000 discovery cycle, reset the counter and + * continue to loop. + * + * Garmin acknowledges this is a firmware defect. + */ + if (rec->type < 0xf8) { + i = 0; + } } + fatal("Failed to find a product inquiry response.\n"); } +carry_on: /* Make sure PVT is off as some GPS' have it on by default */ if(gps_pvt_transfer != -1) GPS_A800_Off(port,&fd); - GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -309,159 +359,118 @@ static void GPS_A001(GPS_PPacket packet) for(i=0;i=100) - { - gps_waypt_type = data; - continue; - } - if(data<153 && data>=150) - { - gps_waypt_type = data; - continue; - } - if(data<156 && data>=154) - { - gps_waypt_type = data; - continue; - } - if (data == 120) - { - /* Quest 3.0 has a D120 for Wpt category ignore it*/ - continue; + switch (data) { + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: + case 108: + case 109: + case 110: + /* 15x is panel-mount aviation */ + case 150: + case 151: + case 152: + /* 153 not documented */ + case 154: + case 155: + gps_waypt_type = data; + break; + + /* + * Observered on Quest 3.0, 27xx, 27x, 29x. + */ + case 120: + gps_category_type = data; + break; + + case 200: + case 201: + case 202: + gps_rte_hdr_type = data; + break; + + /* 210 Link packets appear in newer models, but the + * doc isn't sufficiently clear on what they really + * mean. + */ + case 210: + gps_rte_link_type = data; + break; + } - else - GPS_Protocol_Error(tag,data); } @@ -514,6 +523,7 @@ static void GPS_A001(GPS_PPacket packet) case 301: gps_trk_type = pD301; break; case 302: gps_trk_type = pD302; break; case 303: gps_trk_type = pD303; break; + case 304: gps_trk_type = pD304; break; case 310: gps_trk_hdr_type = pD310; break; case 311: gps_trk_hdr_type = pD311; break; case 312: gps_trk_hdr_type = pD312; break; @@ -525,7 +535,7 @@ static void GPS_A001(GPS_PPacket packet) else if(lasta<500) { - if(data<=109 && data>=100) + if(data<=110 && data>=100) { gps_prx_waypt_type = data; continue; @@ -599,11 +609,23 @@ static void GPS_A001(GPS_PPacket packet) */ continue; } - - + else if (lasta < 1000) + { + if (data == 906) + gps_lap_type = pD906; + } } } + GPS_User("\nLink_type %d Device_command %d\n", + gps_link_type, gps_device_command); + GPS_User("Waypoint: Transfer %d Type %d\n", + gps_waypt_transfer, gps_waypt_type); + GPS_User("Route: Transfer %d Header %d Type %d\n", + gps_route_transfer, gps_rte_hdr_type, gps_rte_type); + GPS_User("Track: Transfer %d Type %d\n", + gps_trk_transfer, gps_trk_type); + return; } @@ -622,14 +644,14 @@ static void GPS_A001(GPS_PPacket packet) int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; int32 i; - if(!GPS_Serial_On(port,&fd)) + if(!GPS_Device_On(port,&fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -668,11 +690,15 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) { if(!((*way)[i]=GPS_Way_New())) return MEMORY_ERROR; - - if(!GPS_Packet_Read(fd, &rec)) + + if(!GPS_Packet_Read(fd, &rec)) { return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) + } + + if(!GPS_Send_Ack(fd, &tra, &rec)) { return gps_errno; + } + switch(gps_waypt_type) { case pD100: @@ -724,7 +750,7 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) GPS_D155_Get(&((*way)[i]),rec->data); break; default: - GPS_Error("A100_GET: Unknown waypoint protocol"); + GPS_Error("A100_GET: Unknown waypoint protocol: %d", gps_waypt_type); return PROTOCOL_ERROR; } /* Issue callback for status updates. */ @@ -740,7 +766,7 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A100_GET: Error transferring waypoints"); + GPS_Error("A100_GET: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); return FRAMING_ERROR; } @@ -753,7 +779,7 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return n; @@ -776,13 +802,13 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; int32 len; - if(!GPS_Serial_On(port,&fd)) + if(!GPS_Device_On(port,&fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -889,13 +915,84 @@ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; } +/* + * Get the list of waypoint categories from the receiver. + */ +int32 GPS_A101_Get(const char *port) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if(!GPS_Device_On(port,&fd)) + return gps_errno; + + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt_Cats); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + + if(!GPS_Write_Packet(fd,tra)) + { + GPS_Error("A101_Get: Cannot write packet"); + return FRAMING_ERROR; + } + + if(!GPS_Get_Ack(fd, &tra, &rec)) + { + GPS_Error("A101_Get: No acknowledge"); + return FRAMING_ERROR; + } + + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); + + n = GPS_Util_Get_Short(rec->data); + for (i = 0; i < n; ++i) { + if(!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if(!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + switch(gps_category_type) { + case pD120: + GPS_D120_Get(i,(char *) rec->data); + break; + } + } + if(!GPS_Packet_Read(fd, &rec)) + return gps_errno; + if(!GPS_Send_Ack(fd, &tra, &rec)) + return gps_errno; + + if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) + { + GPS_Error("A101_Get: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } + + + if(!GPS_Device_Off(fd)) + return gps_errno; + + return 1; + +} /* @funcstatic GPS_D100_Get ********************************************* ** @@ -1295,10 +1392,12 @@ static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) p=s; - (*way)->prot = 109; + (*way)->prot = protoid; + + p++; /* data packet type */ (*way)->wpt_class = *p++; - (*way)->colour = *p++; - (*way)->dspl = *p++; + (*way)->colour = *p & 0x1f; + (*way)->dspl = (*p++ >> 5) & 3; (*way)->attr = *p++; (*way)->smbl = GPS_Util_Get_Short(p); p+=sizeof(int16); @@ -1322,9 +1421,26 @@ static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) p += 4; /* Skip over "outbound link ete in seconds */ if (protoid == 110) { - p += 4; /* skip float temp */ - p += 4; /* skip longword time */ - p += 2; /* skip int "category membership " */ + float gps_temp; + int gps_time; + gps_temp = GPS_Util_Get_Float(p); + p+=4; + if (gps_temp <= 1.0e24) { + (*way)->temperature_populated = 1; + (*way)->temperature = gps_temp; + } + + gps_time = GPS_Util_Get_Uint(p); + p+=4; + /* The spec says that 0xffffffff is unknown, but the 60CSX with + * firmware 2.5.0 writes zero. + */ + if (gps_time != 0xffffffff && gps_time != 0) { + (*way)->time_populated = 1; + (*way)->time = GPS_Math_Gtime_To_Utime(gps_time); + } + (*way)->category = GPS_Util_Get_Short(p); + p += 2; } q = (UC *) (*way)->ident; @@ -1592,6 +1708,32 @@ static void GPS_D155_Get(GPS_PWay *way, UC *s) return; } +/* + * We'll cheat for now. We know there are no more than 16 categories + * as of this writing for no data type exposes more than 16 bits in the + * bitmask of categories. + */ +char gps_categories[16][17]; +/* + * Read descriptor s into category number N; + */ +static +void GPS_D120_Get(int cat_num, char *s) +{ + /* we're guaranteed to have no more than 16 chars plus a + * null terminator. + * + * If the unit returned no string, the user has not configured one, + * so mimic the behaviour of the 276/296. + */ + + if (*s) { + strncpy(gps_categories[cat_num], s, sizeof (gps_categories[0])); + } else { + snprintf(gps_categories[cat_num], sizeof (gps_categories[0]), + "Category %d", cat_num+1); + } +} /* @funcstatic GPS_D100_Send ******************************************* @@ -1921,7 +2063,11 @@ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len) GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); p+=sizeof(int32); - GPS_Util_Put_Float(p,way->alt); + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } p+=sizeof(float); GPS_Util_Put_Float(p,way->dpth); p+=sizeof(float); @@ -1976,11 +2122,13 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) int32 i; p = data; - *p++ = 1 /* way->wpt_class */; /* For D109, the class must be 1 */ - *p++ = 0 /* way->colour*/ ; /* If non-zero, the waypoint is in - invisible ink on the V. */ - *p++ = way->dspl; - if (protoid == 109) { + + *p++ = 1; /* data packet type; must be 1 for D109 and D110 */ + *p++ = 0; // way->wpt_class; + + *p++ = ((way->dspl & 3) << 5) | 0x1f; /* colour & display */ + + if (protoid == 109) { /* attr */ *p++ = 0x70; } else if (protoid == 110) { *p++ = 0x80; @@ -1994,7 +2142,11 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) p+=sizeof(int32); GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); p+=sizeof(int32); - GPS_Util_Put_Float(p,way->alt); + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } p+=sizeof(float); GPS_Util_Put_Float(p,way->dpth); p+=sizeof(float); @@ -2010,14 +2162,15 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) GPS_Util_Put_Float(p, temp); p += 4; - if (way->Time_populated) { - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->Time)); + if (way->time_populated) { + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->time)); p+=sizeof(uint32); } else { for(i=0;i<4;++i) *p++ = 0xff; /* unknown time*/ } - for(i=0;i<2;++i) *p++ = 0x00; /* D110 category */ + GPS_Util_Put_Short(p, (US) way->category);; /* D110 category */ + p += 2; } q = (UC *) way->ident; @@ -2300,14 +2453,14 @@ static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len) int32 GPS_A200_Get(const char *port, GPS_PWay **way) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; int32 i; - if(!GPS_Serial_On(port,&fd)) + if(!GPS_Device_On(port,&fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -2455,7 +2608,7 @@ int32 GPS_A200_Get(const char *port, GPS_PWay **way) GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return n; @@ -2475,14 +2628,14 @@ int32 GPS_A200_Get(const char *port, GPS_PWay **way) int32 GPS_A201_Get(const char *port, GPS_PWay **way) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; int32 i; - if(!GPS_Serial_On(port,&fd)) + if(!GPS_Device_On(port,&fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -2648,7 +2801,7 @@ int32 GPS_A201_Get(const char *port, GPS_PWay **way) GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return n; @@ -2669,14 +2822,14 @@ int32 GPS_A201_Get(const char *port, GPS_PWay **way) int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; int32 len; UC method; - if(!GPS_Serial_On(port,&fd)) + if(!GPS_Device_On(port,&fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -2797,7 +2950,7 @@ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -2818,14 +2971,14 @@ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; int32 len; UC method; - if(!GPS_Serial_On(port,&fd)) + if(!GPS_Device_On(port,&fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -2966,7 +3119,7 @@ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -3195,10 +3348,10 @@ static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len) ** ** @return [int32] number of track entries ************************************************************************/ -int32 GPS_A300_Get(const char *port, GPS_PTrack **trk) +int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; @@ -3216,7 +3369,7 @@ int32 GPS_A300_Get(const char *port, GPS_PTrack **trk) return GPS_UNSUPPORTED; } - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -3247,7 +3400,6 @@ int32 GPS_A300_Get(const char *port, GPS_PTrack **trk) for(i=0;itype == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + break; + } + } + return 0; +} /* @func GPS_A301_Get ****************************************************** ** @@ -3287,10 +3479,10 @@ int32 GPS_A300_Get(const char *port, GPS_PTrack **trk) ** ** @return [int32] number of track entries ************************************************************************/ -int32 GPS_A301_Get(const char *port, GPS_PTrack **trk) +int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; @@ -3306,9 +3498,13 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk) return GPS_UNSUPPORTED; } - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; + if ((gps_trk_type == pD304) && gps_run_transfer) { + drain_run_cmd(fd); + } + if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) return MEMORY_ERROR; @@ -3338,14 +3534,12 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk) if(!((*trk)[i]=GPS_Track_New())) return MEMORY_ERROR; - for(i=0;itype == LINK_ID[gps_link_type].Pid_Trk_Hdr) { switch(gps_trk_hdr_type) @@ -3385,19 +3579,21 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk) GPS_D302b_Get(&((*trk)[i]),rec->data); break; case pD303: + case pD304: GPS_D303b_Get(&((*trk)[i]),rec->data); break; default: GPS_Error("A301_GET: Unknown track protocol"); return PROTOCOL_ERROR; } + /* Cheat and don't _really_ pass the trkpt back */ + cb(n, NULL); } if(!GPS_Packet_Read(fd, &rec)) return gps_errno; if(!GPS_Send_Ack(fd, &tra, &rec)) return gps_errno; - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { GPS_Error("A301_Get: Error transferring tracks"); @@ -3413,7 +3609,7 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return n; @@ -3436,7 +3632,7 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk) int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; @@ -3452,7 +3648,7 @@ int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) return GPS_UNSUPPORTED; } - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -3509,7 +3705,7 @@ int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -3530,7 +3726,7 @@ int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; @@ -3547,7 +3743,7 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n) return GPS_UNSUPPORTED; } - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -3631,7 +3827,7 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -3649,7 +3845,7 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n) ** ** @return [int32] number of entries read ************************************************************************/ -int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, int32 fd) +int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *fd) { GPS_PPacket tra; GPS_PPacket rec; @@ -3761,7 +3957,7 @@ void GPS_D302b_Get(GPS_PTrack *trk, UC *data) { UC *p; uint32 t; - double temp; + double gps_temp; p=data; @@ -3787,7 +3983,12 @@ void GPS_D302b_Get(GPS_PTrack *trk, UC *data) /* The only difference between 302 and 301 is the presence of temp * in the middle. Nice planning, eh? */ - temp = GPS_Util_Get_Float(p); + gps_temp = GPS_Util_Get_Float(p); + if (gps_temp <= 1.0e24) { + (*trk)->temperature_populated = 1; + (*trk)->temperature = gps_temp; + } + p+=sizeof(float); (*trk)->tnew = *p; @@ -3811,8 +4012,6 @@ void GPS_D303b_Get(GPS_PTrack *trk, UC *data) uint32 t; uint32 raw_lat, raw_lon; int lat_undefined, lon_undefined; - int i; - p=data; /* Latitude and longitude are sometimes invalid (0x7fffffff or @@ -3836,10 +4035,19 @@ void GPS_D303b_Get(GPS_PTrack *trk, UC *data) (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon); p+=sizeof(int32); + /* + * Let the caller decide if it wants to toss trackpionts with only + * hear and/or time data. + */ + if (lat_undefined || lon_undefined) { + (*trk)->no_latlon = 1; + } + if (lat_undefined != lon_undefined) GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated"); t = GPS_Util_Get_Uint(p); + if(!t || t==0x7fffffff || t==0xffffffff) (*trk)->Time=0; else @@ -3853,12 +4061,27 @@ void GPS_D303b_Get(GPS_PTrack *trk, UC *data) p+=sizeof(float); /* Heartrate is reported as 0 if there is no signal from - * a heartrate monitor. A uint32 is a bit overkill, even - * for me in my state of fitness. Perhaps this is actually - * a char or uint16, leaving room for a trk_seg bool at the end? + * a heartrate monitor. + * 305 and 304 are identical until now. */ - (*trk)->heartrate = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + switch (gps_trk_type) { + case pD304: + p+=4; /* A float indicating number of meters travelled. */ + + (*trk)->heartrate = (*p++); + /* crank cadence, RPM, 0xff if invalid. */ + if (*p != 0xff) { + (*trk)->cadence = (*p); + } + + /* sensor present. Boolean */ + p++; + + break; + case pD303: + (*trk)->heartrate = *p++; + break; + } /* There doesn't seem to be a trk_seg bool, or at least I've not * observed it yet. One possibility is to start a new segment @@ -3915,6 +4138,7 @@ void GPS_D311_Get(GPS_PTrack *trk, UC *s) /* Forerunner */ identifier = GPS_Util_Get_Short(s); sprintf((*trk)->trk_ident, "%d", identifier); + (*trk)->tnew = 1; return; } @@ -4078,7 +4302,7 @@ static void GPS_A300_Encode(UC *s, GPS_PTrack trk) int32 GPS_A400_Get(const char *port, GPS_PWay **way) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; @@ -4088,7 +4312,7 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way) return GPS_UNSUPPORTED; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -4104,13 +4328,13 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way) if(!GPS_Get_Ack(fd, &tra, &rec)) return gps_errno; - if(!GPS_Serial_Chars_Ready(fd)) + if(!GPS_Device_Chars_Ready(fd)) { GPS_Warning("A400 (ppx) protocol not supported"); GPS_Packet_Del(&rec); GPS_Packet_Del(&tra); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return GPS_UNSUPPORTED; @@ -4220,7 +4444,7 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return n; @@ -4241,7 +4465,7 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way) int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; @@ -4250,7 +4474,7 @@ int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n) if(gps_prx_waypt_transfer == -1) return GPS_UNSUPPORTED; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -4347,7 +4571,7 @@ int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -4604,14 +4828,14 @@ static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len) int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 n; int32 i; int32 ret; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -4675,7 +4899,7 @@ int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return ret; @@ -4698,7 +4922,7 @@ int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) { UC data[GPS_ARB_LEN]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 i; @@ -4707,7 +4931,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) int32 posnsent; int32 ret; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -4796,7 +5020,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) * the time. Note that the time sent is held in gps_save_time * global */ - if(GPS_Serial_Wait(fd)) + if(GPS_Device_Wait(fd)) { if(!GPS_Packet_Read(fd, &rec)) return gps_errno; @@ -4822,7 +5046,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) * the position. Note that the posn sent is held in gps_save_lat * and gps_save_lon global! */ - if(GPS_Serial_Wait(fd)) + if(GPS_Device_Wait(fd)) { if(!GPS_Packet_Read(fd, &rec)) return gps_errno; @@ -4858,7 +5082,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -4876,7 +5100,7 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) ** ** @return [int32] number of entries read ************************************************************************/ -static int32 GPS_D500_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) +static int32 GPS_D500_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd) { GPS_PPacket tra; GPS_PPacket rec; @@ -4928,7 +5152,7 @@ static int32 GPS_D500_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) ** ** @return [int32] number of entries read ************************************************************************/ -static int32 GPS_D501_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) +static int32 GPS_D501_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd) { GPS_PPacket tra; GPS_PPacket rec; @@ -4980,7 +5204,7 @@ static int32 GPS_D501_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) ** ** @return [int32] number of entries read ************************************************************************/ -static int32 GPS_D550_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) +static int32 GPS_D550_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd) { GPS_PPacket tra; GPS_PPacket rec; @@ -5031,7 +5255,7 @@ static int32 GPS_D550_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) ** ** @return [int32] number of entries read ************************************************************************/ -static int32 GPS_D551_Get(GPS_PAlmanac *alm, int32 entries, int32 fd) +static int32 GPS_D551_Get(GPS_PAlmanac *alm, int32 entries, gpsdevh *fd) { GPS_PPacket tra; GPS_PPacket rec; @@ -5276,18 +5500,17 @@ static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm) time_t GPS_A600_Get(const char *port) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; time_t ret; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) return MEMORY_ERROR; - GPS_Util_Put_Short(data, COMMAND_ID[gps_device_command].Cmnd_Transfer_Time); GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, @@ -5315,7 +5538,7 @@ time_t GPS_A600_Get(const char *port) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return ret; @@ -5336,13 +5559,13 @@ time_t GPS_A600_Get(const char *port) ************************************************************************/ int32 GPS_A600_Send(const char *port, time_t Time) { - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; int32 posnsent=0; int32 ret=0; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -5369,7 +5592,7 @@ int32 GPS_A600_Send(const char *port, time_t Time) * the position. Note that the posn sent is held in gps_save_lat * and gps_save_lon globals! */ - if(GPS_Serial_Wait(fd)) + if(GPS_Device_Wait(fd)) { if(!GPS_Packet_Read(fd, &rec)) return gps_errno; @@ -5399,7 +5622,7 @@ int32 GPS_A600_Send(const char *port, time_t Time) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -5488,11 +5711,11 @@ void GPS_D600_Send(GPS_PPacket *packet, time_t Time) int32 GPS_A700_Get(const char *port, double *lat, double *lon) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -5526,7 +5749,7 @@ int32 GPS_A700_Get(const char *port, double *lat, double *lon) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -5546,11 +5769,11 @@ int32 GPS_A700_Get(const char *port, double *lat, double *lon) ************************************************************************/ int32 GPS_A700_Send(const char *port, double lat, double lon) { - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -5576,7 +5799,7 @@ int32 GPS_A700_Send(const char *port, double lat, double lon) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -5655,13 +5878,13 @@ void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A800_On(const char *port, int32 *fd) +int32 GPS_A800_On(const char *port, gpsdevh **fd) { static UC data[2]; GPS_PPacket tra; GPS_PPacket rec; - if(!GPS_Serial_On(port, fd)) + if(!GPS_Device_On(port, fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -5697,7 +5920,7 @@ int32 GPS_A800_On(const char *port, int32 *fd) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A800_Off(const char *port, int32 *fd) +int32 GPS_A800_Off(const char *port, gpsdevh **fd) { static UC data[2]; GPS_PPacket tra; @@ -5723,8 +5946,8 @@ int32 GPS_A800_Off(const char *port, int32 *fd) GPS_Packet_Del(&rec); GPS_Packet_Del(&tra); - if(!GPS_Serial_Off(port, *fd)) - return gps_errno; +// if(!GPS_Device_Off(*fd)) +// return gps_errno; return 1; } @@ -5739,7 +5962,7 @@ int32 GPS_A800_Off(const char *port, int32 *fd) ** ** @return [int32] success ************************************************************************/ -int32 GPS_A800_Get(int32 *fd, GPS_PPvt_Data *packet) +int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) { GPS_PPacket tra; GPS_PPacket rec; @@ -5754,6 +5977,10 @@ int32 GPS_A800_Get(int32 *fd, GPS_PPvt_Data *packet) if(!GPS_Send_Ack(*fd, &tra, &rec)) return gps_errno; + + if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { + return 0; + } switch(gps_pvt_type) { @@ -5831,7 +6058,127 @@ void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) return; } +#if XXX /* FIXME/PLACEHOLDER */ + +/* @func GPS_A906_Get ****************************************************** +** +** Get lap data from GPS +** +** @param [r] port [const char *] serial port +** @param [w] trk [GPS_PLap_Data **] lap array +** +** @return [int32] number of lap entries +************************************************************************/ +int32 GPS_A906_Get(const char *port, GPS_OLap_Data **lap) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket lappkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_lap_transfer == -1) + return GPS_UNSUPPORTED; + + if (!GPS_Device_On(port, &fd)) + return gps_errno; + + if (!(lappkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Lap); + GPS_Make_Packet(&lappkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,lappkt)) + return gps_errno; + if(!GPS_Get_Ack(fd, &lappkt, &recpkt)) + return gps_errno; + if(!GPS_Packet_Read(fd, &recpkt)) + return gps_errno; + if(!GPS_Send_Ack(fd, &lappkt, &recpkt)) + return gps_errno; + + n = GPS_Util_Get_Short(recpkt->data); + + if(n) + if(!((*lap)=(GPS_PLap *)malloc(n*sizeof(GPS_PLap)))) + { + GPS_Error("A906_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + for(i=0;idata; + + t = GPS_Util_Get_Uint(p); + (*Lap)->start_time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*Lap)->total_time = GPS_Util_Get_Int(p); + p+=sizeof(int32); + + (*Lap)->total_distance = GPS_Util_Get_Float(p); + p+=sizeof(float); + + + (*Lap)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*Lap)->calories = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + (*Lap)->track_index = *p++; + + return; +} /* * It's unfortunate that these aren't constant and therefore switchable, @@ -5839,7 +6186,7 @@ void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) */ const char * -Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo) +Get_Pkt_Type(unsigned char p, unsigned short d0, const char **xinfo) { *xinfo = NULL; #define LT LINK_ID[gps_link_type] @@ -5860,6 +6207,12 @@ Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo) case 50: *xinfo = "Xfer PVT Stop"; break; case 92: *xinfo = "Flight Records"; break; case 117: *xinfo = "Xfer Laps"; break; + case 121: *xinfo = "Xfer Categories"; break; + case 450: *xinfo = "Xfer Runs"; break; + case 451: *xinfo = "Xfer Workouts"; break; + case 452: *xinfo = "Xfer Wkt Occurrences"; break; + case 453: *xinfo = "Xfer User Profile "; break; + case 454: *xinfo = "Xfer Wkt Limits"; break; default: *xinfo = "Unknown"; } return "CMDDAT"; @@ -5898,5 +6251,13 @@ Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo) return "PRDREQ"; if (p == LT.Pid_Product_Data) return "PRDDAT"; + if (p == GUSB_REQUEST_BULK) + return "REQBLK"; + if (p == GUSB_SESSION_START) + return "SESREQ"; + if (p == GUSB_SESSION_ACK) + return "SESACK"; + if (p == 152) + return "WPTCAT"; return "UNKNOWN"; } diff --git a/jeeps/gpsapp.h b/jeeps/gpsapp.h index a8f6ffb13..2d9ead9c1 100644 --- a/jeeps/gpsapp.h +++ b/jeeps/gpsapp.h @@ -12,6 +12,7 @@ extern "C" int32 GPS_Init(const char *port); int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int ct, GPS_PWay *)); +int32 GPS_A101_Get(const char *port); int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)); int32 GPS_A200_Get(const char *port, GPS_PWay **way); @@ -19,12 +20,12 @@ int32 GPS_A201_Get(const char *port, GPS_PWay **way); int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n); int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n); -int32 GPS_A300_Get(const char *port, GPS_PTrack **trk); -int32 GPS_A301_Get(const char *port, GPS_PTrack **trk); +int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); +int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n); int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n); -int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, int32 fd); +int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *h); void GPS_D300b_Get(GPS_PTrack *trk, UC *data); void GPS_D301b_Get(GPS_PTrack *trk, UC *data); void GPS_D302b_Get(GPS_PTrack *trk, UC *data); @@ -51,12 +52,12 @@ int32 GPS_A700_Send(const char *port, double lat, double lon); void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon); void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon); -int32 GPS_A800_On(const char *port, int32 *fd); -int32 GPS_A800_Off(const char *port, int32 *fd); -int32 GPS_A800_Get(int32 *fd, GPS_PPvt_Data *packet); +int32 GPS_A800_On(const char *port, gpsdevh **fd); +int32 GPS_A800_Off(const char *port, gpsdevh **fd); +int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet); void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt); -const char * Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo); +const char * Get_Pkt_Type(unsigned char p, unsigned short d0, const char **xinfo); #endif diff --git a/jeeps/gpscom.c b/jeeps/gpscom.c index b3d6b3e05..e2fe2afd6 100644 --- a/jeeps/gpscom.c +++ b/jeeps/gpscom.c @@ -4,6 +4,7 @@ ** @author Copyright (C) 1999 Alan Bleasby ** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2005, 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -35,15 +36,13 @@ int32 GPS_Command_Off(const char *port) { static UC data[2]; - int32 fd; + gpsdevh *fd; GPS_PPacket tra; GPS_PPacket rec; GPS_Util_Little(); - gps_is_usb = (0 == strncmp(port, "usb:", 4)); - - if(!GPS_Serial_On(port, &fd)) + if(!GPS_Device_On(port, &fd)) return gps_errno; if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) @@ -57,7 +56,7 @@ int32 GPS_Command_Off(const char *port) if(!GPS_Write_Packet(fd,tra)) return gps_errno; - if(!GPS_Serial_Chars_Ready(fd)) + if(!GPS_Device_Chars_Ready(fd)) { if(!GPS_Get_Ack(fd, &tra, &rec)) return gps_errno; @@ -67,7 +66,7 @@ int32 GPS_Command_Off(const char *port) GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); - if(!GPS_Serial_Off(port, fd)) + if(!GPS_Device_Off(fd)) return gps_errno; return 1; @@ -84,10 +83,23 @@ int32 GPS_Command_Off(const char *port) ** @return [int32] number of waypoint entries ************************************************************************/ -int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, int (*cb)(int, struct GPS_SWay **)) +int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, pcb_fn cb) { int32 ret=0; + /* + * It's a bit tacky to do this up front without ticking the + * progress meter, but this come in pretty quickly... + */ + if (gps_category_transfer) { + ret = GPS_A101_Get(port); + if (!ret) { +fatal("blah"); + return PROTOCOL_ERROR; + } + + } + switch(gps_waypt_transfer) { case pA100: @@ -207,7 +219,7 @@ int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n) ** @return [int32] number of track entries ************************************************************************/ -int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk) +int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, pcb_fn cb) { int32 ret=0; @@ -217,14 +229,14 @@ int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk) switch(gps_trk_transfer) { case pA300: - ret = GPS_A300_Get(port,trk); + ret = GPS_A300_Get(port,trk,cb); break; case pA301: case pA302: - ret = GPS_A301_Get(port,trk); + ret = GPS_A301_Get(port,trk,cb); break; default: - GPS_Error("Get_Track: Unknown track protocol\n"); + GPS_Error("Get_Track: Unknown track protocol %d\n", gps_trk_transfer); return PROTOCOL_ERROR; } @@ -412,6 +424,12 @@ time_t GPS_Command_Get_Time(const char *port) case pA600: ret = GPS_A600_Get(port); break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), + * but don't treat as error; return as zero. + */ + case -1: + return 0; default: GPS_Error("Get_Time: Unknown date/time protocol"); return PROTOCOL_ERROR; @@ -472,6 +490,13 @@ int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon) case pA700: ret = GPS_A700_Get(port,lat,lon); break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), + * zero lat/lon, but don't treat as error. + */ + case -1: + *lat = *lon = 0.0; + break; default: GPS_Error("Get_Position: Unknown position protocol"); return PROTOCOL_ERROR; @@ -521,7 +546,7 @@ int32 GPS_Command_Send_Position(const char *port, double lat, double lon) ** @return [int32] success if supported and GPS starts sending ************************************************************************/ -int32 GPS_Command_Pvt_On(const char *port, int32 *fd) +int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd) { int32 ret=0; @@ -556,7 +581,7 @@ int32 GPS_Command_Pvt_On(const char *port, int32 *fd) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Pvt_Off(const char *port, int32 *fd) +int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd) { int32 ret=0; @@ -589,7 +614,7 @@ int32 GPS_Command_Pvt_Off(const char *port, int32 *fd) ** @return [int32] success ************************************************************************/ -int32 GPS_Command_Pvt_Get(int32 *fd, GPS_PPvt_Data *pvt) +int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt) { int32 ret=0; diff --git a/jeeps/gpscom.h b/jeeps/gpscom.h index e8bbe1d2a..96e10f055 100644 --- a/jeeps/gpscom.h +++ b/jeeps/gpscom.h @@ -18,14 +18,14 @@ int32 GPS_Command_Send_Time(const char *port, time_t Time); int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon); int32 GPS_Command_Send_Position(const char *port, double lat, double lon); -int32 GPS_Command_Pvt_On(const char *port, int32 *fd); -int32 GPS_Command_Pvt_Off(const char *port, int32 *fd); -int32 GPS_Command_Pvt_Get(int32 *fd, GPS_PPvt_Data *pvt); +int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd); +int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd); +int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt); int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm); int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n); -int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk); +int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, int (*cb)(int, struct GPS_SWay **)); int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n); int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)(int, struct GPS_SWay **)); diff --git a/jeeps/gpsdatum.h b/jeeps/gpsdatum.h index f62405664..054c11608 100644 --- a/jeeps/gpsdatum.h +++ b/jeeps/gpsdatum.h @@ -173,7 +173,7 @@ GPS_ODatum GPS_Datum[]= /* 111 */ { "Timbalai 1948", 7, -689, 691, -45 }, /* 112 */ { "Tokyo mean", 4, -128, 481, 664 }, /* 113 */ { "Tristan Astro 1968", 17, -632, 438, -609 }, -/* 114 */ { "Unites Arab Emirates", 6, -249, -156, 381 }, +/* 114 */ { "United Arab Emirates", 6, -249, -156, 381 }, /* 115 */ { "Viti Levu 1916", 6, 51, 391, -36 }, /* 116 */ { "Wake Eniwetok 60", 15, 101, 52, -39 }, /* 117 */ { "WGS 72", 25, 0, 0, 5 }, diff --git a/jeeps/gpsdevice.c b/jeeps/gpsdevice.c new file mode 100644 index 000000000..90c841f1b --- /dev/null +++ b/jeeps/gpsdevice.c @@ -0,0 +1,86 @@ +/* + Abstraction of underlying device types, serial or USB. OS agnostic.. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software{} you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation{} either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY{} without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program{} if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gps.h" +#include "gpsdevice.h" +#include "gpsserial.h" + +extern gps_device_ops gps_serial_ops; +extern gps_device_ops gps_usb_ops; +gps_device_ops *ops = NULL; + +int32 GPS_Device_On(const char *port, gpsdevh **fd) +{ + gps_is_usb = (0 == case_ignore_strncmp(port, "usb:", 4)); + + if (gps_is_usb) { + ops = &gps_usb_ops; + } else { + ops = &gps_serial_ops; + } + + return (ops->Device_On)(port, fd); +} + +int32 GPS_Device_Off(gpsdevh * fd) +{ + return (ops->Device_Off)(fd); +} + +int32 GPS_Device_Wait(gpsdevh * fd) +{ + return (ops->Device_Wait)(fd); +} + +int32 GPS_Device_Chars_Ready(gpsdevh * fd) +{ + return (ops->Device_Chars_Ready)(fd); +} + +int32 GPS_Device_Flush(gpsdevh * fd) +{ + return (ops->Device_Flush)(fd); +} + +int32 GPS_Write_Packet(gpsdevh * fd, GPS_PPacket packet) +{ + return (ops->Write_Packet)(fd, packet); +} + +int32 GPS_Packet_Read(gpsdevh * fd, GPS_PPacket *packet) +{ + return (ops->Read_Packet)(fd, packet); +} + +int32 GPS_Send_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) +{ + return (ops->Send_Ack)(fd, tra, rec); +} + +int32 GPS_Get_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) +{ + return (ops->Get_Ack)(fd, tra, rec); +} + +void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n) +{ + (ops->Make_Packet)(packet, type, data, n); +} diff --git a/jeeps/gpsdevice.h b/jeeps/gpsdevice.h new file mode 100644 index 000000000..eb5d53d96 --- /dev/null +++ b/jeeps/gpsdevice.h @@ -0,0 +1,73 @@ +/* + Abstraction of underlying device types. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef gpsdevice_h +#define gpsdevice_h + +typedef struct gpsdevh gpsdevh; + +#include "gps.h" + +#define usecDELAY 180000 /* Microseconds before GPS sends A001 */ + + +int32 GPS_Device_Chars_Ready(gpsdevh *fd); +int32 GPS_Device_On(const char *port, gpsdevh **fd); +int32 GPS_Device_Off(gpsdevh *fd); +int32 GPS_Device_Wait(gpsdevh * fd); +int32 GPS_Device_Flush(gpsdevh * fd); +int32 GPS_Device_Read(int32 ignored, void *ibuf, int size); +int32 GPS_Device_Write(int32 ignored, const void *obuf, int size); +void GPS_Device_Error(char *hdr, ...); +int32 GPS_Write_Packet(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); +int32 GPS_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); +int32 GPS_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + +typedef int32 (*gps_device_op)(gpsdevh *); +typedef int32 (*gps_device_op5)(const char *, gpsdevh **fd); +typedef int32 (*gps_device_op10)(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec); +typedef int32 (*gps_device_op12)(gpsdevh * fd, GPS_PPacket packet); +typedef int32 (*gps_device_op13)(gpsdevh * fd, GPS_PPacket *packet); +typedef void (*gps_device_op14)(GPS_PPacket *packet, UC type, UC *data, int16 n); +typedef struct { + gps_device_op5 Device_On; + gps_device_op Device_Off; + gps_device_op Device_Chars_Ready; + gps_device_op Device_Wait; + gps_device_op Device_Flush; + gps_device_op10 Send_Ack; + gps_device_op10 Get_Ack; + gps_device_op13 Read_Packet; + gps_device_op14 Make_Packet; + gps_device_op12 Write_Packet; +} gps_device_ops; + +#endif /* gpsdevice.h */ + +#ifdef __cplusplus +} +#endif diff --git a/jeeps/gpsdevice_ser.c b/jeeps/gpsdevice_ser.c new file mode 100644 index 000000000..29ff476e6 --- /dev/null +++ b/jeeps/gpsdevice_ser.c @@ -0,0 +1,37 @@ +/* + Serial operations. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gpsdevice.h" +#include "gpsserial.h" +#include "gpsread.h" + +gps_device_ops gps_serial_ops = { + GPS_Serial_On, + GPS_Serial_Off, + GPS_Serial_Chars_Ready, + GPS_Serial_Wait, + GPS_Serial_Flush, + GPS_Serial_Send_Ack, + GPS_Serial_Get_Ack, + GPS_Serial_Packet_Read, + GPS_Serial_Make_Packet, + GPS_Serial_Write_Packet, +}; diff --git a/jeeps/gpsdevice_usb.c b/jeeps/gpsdevice_usb.c new file mode 100644 index 000000000..dd578c829 --- /dev/null +++ b/jeeps/gpsdevice_usb.c @@ -0,0 +1,59 @@ +/* + USB operations. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gpsdevice.h" +#include "garminusb.h" +#include "gpsusbint.h" +#include "gpsusbcommon.h" + +static int32 success_stub(void) +{ + return 1; +} + +static int32 gdu_on(const char *port, gpsdevh **fd) +{ + return gusb_init(port, fd); +} + +static int32 gdu_off(gpsdevh *dh) +{ + return gusb_close(dh); +} + +static int32 gdu_read(gpsdevh *fd, GPS_PPacket *packet) +{ + /* Default is to eat bulk request packets. */ + return GPS_Packet_Read_usb(fd, packet, 1); +} + +gps_device_ops gps_usb_ops = { + gdu_on, + gdu_off, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op10) success_stub, + (gps_device_op10) success_stub, + gdu_read, + GPS_Make_Packet_usb, + GPS_Write_Packet_usb +}; diff --git a/jeeps/gpslibusb.c b/jeeps/gpslibusb.c index 7121b6423..225f35a47 100644 --- a/jeeps/gpslibusb.c +++ b/jeeps/gpslibusb.c @@ -1,8 +1,7 @@ -#if !defined(NO_USB) /* Physical/OS USB layer to talk to libusb. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,9 +22,12 @@ #include #include +#include "config.h" +#if HAVE_LIBUSB #include #include "gps.h" #include "garminusb.h" +#include "gpsusbcommon.h" #define GARMIN_VID 0x91e @@ -38,102 +40,158 @@ * coalescion into packets anyway becuase of their serial background) will * compensate. */ -#define TMOUT_I 0100 /* Milliseconds to timeout intr pipe access. */ +#define TMOUT_I 3000 /* Milliseconds to timeout intr pipe access. */ +#define TMOUT_B 3000 /* Milliseconds to timeout bulk pipe access. */ -int gusb_intr_in_ep; -int gusb_bulk_out_ep; -int gusb_bulk_in_ep; +typedef struct { + struct usb_bus *busses; +} libusb_unit_data; -static const char oinit[12] = {0, 0, 0, 0, 0x05, 0, 0, 0, 0, 0, 0, 0}; -garmin_usb_packet iresp; - -static struct usb_bus *busses; -static usb_dev_handle *udev; -static void garmin_usb_scan(void); -static void garmin_usb_syncup(void); - -int -gusb_init(void) -{ -// usb_set_debug(99); - usb_init(); - usb_find_busses(); - usb_find_devices(); - busses = usb_get_busses(); - garmin_usb_scan(); - - return 1; -} +/* + * TODO: this should all be moved into libusbdata in gpslibusb.h, + * allocated once here in gusb_start, and deallocated at the end. + */ +static int gusb_intr_in_ep; +static int gusb_bulk_out_ep; +static int gusb_bulk_in_ep; +static gusb_llops_t libusb_llops; -static void dump(char *msg, const unsigned char *in, int r) -{ - int i; - printf("%s: %d\n", msg, r); - for (i = 0; i < r; i++) { - printf ("%02x ", in[i]); - } - if (r) printf("\n"); - for (i = 0; i < r; i++) { - printf ("%c", isalnum(in[i]) ? in[i] : '.'); - } - if (r) printf("\n"); -} +static usb_dev_handle *udev; +static void garmin_usb_scan(libusb_unit_data *, int); -int -gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) +static int +gusb_libusb_send(const garmin_usb_packet *opkt, size_t sz) { int r; + r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_B); - r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_I); - if (gps_show_bytes) { - dump ("Sent", &opkt->dbuf[0], r); - } - if (r != sz) { - fprintf(stderr, "Bad cmdsend r %d sz %d\n", r, sz); + if (r != (int) sz) { + fprintf(stderr, "Bad cmdsend r %d sz %ld\n", r, (unsigned long) sz); if (r < 0) { fatal("usb_bulk_write failed. '%s'\n", usb_strerror()); } } + return r; } -int -gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) +static int +gusb_libusb_get(garmin_usb_packet *ibuf, size_t sz) { unsigned char *buf = &ibuf->dbuf[0]; - unsigned char *obuf = buf; - int r = -1, tsz = 0; + int r = -1; r = usb_interrupt_read(udev, gusb_intr_in_ep, (char *) buf, sz, TMOUT_I); + return r; +} - tsz = r; - - if (gps_show_bytes) { - int i; - const char *m1, *m2; - printf("RX [%d]:", tsz); - for(i=0;idbuf[0]; - m1 = Get_Pkt_Type(ibuf->gusb_pkt.pkt_id[0], ibuf->gusb_pkt.databuf[0], &m2); - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - printf("\n"); - } + r = usb_bulk_read(udev, gusb_bulk_in_ep, (char *) buf, sz, TMOUT_B); - return (r); + return r; } -void -garmin_usb_teardown(void) + +static int +gusb_teardown(gpsdevh *dh) { if (udev) { usb_release_interface(udev, 0); usb_close(udev); udev = NULL; } + return 0; +} + +/* + * This is a function of great joy to discover. + * + * It turns out that as of 5/2006, every Garmin USB product has a problem + * where the device does not reset the data toggles after a configuration + * set. After a reset, the toggles both match. So we tear through the + * conversation and life is good. Unfortunately, the second time through, + * if we had an odd number of transactions in the previous conversation, + * we send a configuration set and reset the toggle on the HCI but the + * toggle on the device's end of the pipe is now out of whack which means + * that the subsequent transaction will hang. + * + * This isn't a problem in Windows since the configuration set is done only + * once there. + * + * This code has been tested in loops of 1000 cycles on Linux and OS/X and + * it seems to cure this at a mere cost of complexity and startup time. I'll + * be delighted when all the firmware gets revved and updated and we can + * remove this. + * + */ +static void +gusb_reset_toggles(void) +{ + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int t; + + /* Start off with three session starts. + * #1 resets the bulk out toggle. It may not make it to the device. + * #2 resets the the intr in toggle. It will make it to the device + * since #1 reset the the bulk out toggle. The device will + * respond on the intr in pipe which will clear its toggle. + * #3 actually starts the session now that the above are both clear. + */ + + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + + t = 10; + while(1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + break; + } + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } + + /* + * Now that the bulk out and intr in packets are good, we send + * a product ID. On devices that respond totally on the intr + * pipe, this does nothing interesting, but on devices that respon + * on the bulk pipe this will reset the toggles on the bulk in. + */ + t = 10; + gusb_cmd_send((const garmin_usb_packet *) oid, sizeof(oid)); + while(1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + } + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return; + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } } void @@ -143,36 +201,40 @@ garmin_usb_start(struct usb_device *dev) if (udev) return; - /* - * Linux _requires_ the reset. OSX doesn't work if we DO reset it. - * I really should study this more, but for now, we'll just avoid the - * reset on Apple's OSX. - */ -#if !defined (__APPLE__) udev = usb_open(dev); - usb_reset(udev); - usb_close(udev); -#endif /* APPLE */ + atexit((void(*)())gusb_teardown); - udev = usb_open(dev); - atexit(garmin_usb_teardown); - if (!udev) { fatal("usb_open failed\n"); } + if (!udev) { fatal("usb_open failed: %s\n", usb_strerror()); } /* * Hrmph. No iManufacturer or iProduct headers.... */ if (usb_set_configuration(udev, 1) < 0) { - fatal("usb_set_configuration failed\n"); +#if __linux__ + char drvnm[128]; + drvnm[0] = 0; + /* + * Most Linux distributions ship a slightly broken + * kernel driver that bonds with the hardware. + */ + usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); + fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" + "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); +#else + + fatal("usb_set_configuration failed: %s\n", usb_strerror()); +#endif } if (usb_claim_interface(udev, 0) < 0) { -// abort(); + fatal("Claim interfaced failed: %s\n", usb_strerror()); } - + libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { struct usb_endpoint_descriptor * ep; ep = &dev->config->interface->altsetting->endpoint[i]; + switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { #define EA(x) x & USB_ENDPOINT_ADDRESS_MASK case USB_ENDPOINT_TYPE_BULK: @@ -193,49 +255,23 @@ garmin_usb_start(struct usb_device *dev) * that loop without non-zero values for all three, we're hosed. */ if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { - garmin_usb_syncup(); - } else { - fatal("Could not identify endpoints on USB device.\nFound endpoints Intr In %d Bulk Out %d Bulk In %d\n", gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); + gusb_reset_toggles(); + gusb_syncup(); + return; } - return; -} - -void -garmin_usb_syncup(void) -{ - int maxct = 5; - int maxtries; - - for (maxtries = maxct; maxtries; maxtries--) { - - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_get(&iresp, sizeof(iresp)); - - if ((le_read16(iresp.gusb_pkt.pkt_id) == 6) && - (le_read32(iresp.gusb_pkt.datasz) == 4)) { - if (gps_show_bytes) { - fprintf(stderr, "Synced in %d\n", maxct - maxtries); - } -// fprintf(stderr, "Unit number %u\n", iresp[15] << 24 | iresp[14] << 16 | iresp[13] << 8 | iresp[12]); - return; - } - } -return; - fatal("Cannot sync up with receiver\n"); + fatal("Could not identify endpoints on USB device.\n" + "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", + gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); } static -void garmin_usb_scan(void) +void garmin_usb_scan(libusb_unit_data *lud, int req_unit_number) { - int initted = 0; + int found_devices = 0; struct usb_bus *bus; - for (bus = busses; bus; bus = bus->next) { + for (bus = lud->busses; bus; bus = bus->next) { struct usb_device *dev; for (dev = bus->devices; dev; dev = dev->next) { @@ -244,15 +280,68 @@ void garmin_usb_scan(void) * we just take the easy way out for now. */ if (dev->descriptor.idVendor == GARMIN_VID) { - garmin_usb_start(dev); - initted++; + /* Nuvi */ + if (dev->descriptor.idProduct == 0x19) + continue; + if (req_unit_number < 0) { + garmin_usb_start(dev); + /* + * It's important to call _close + * here since the bulk/intr models + * may have a "dangling" packet that + * needs to be drained. + */ + gusb_close(NULL); + } else + if (req_unit_number == found_devices) + garmin_usb_start(dev); + found_devices++; } } } - if (0 == initted) { + if (req_unit_number < 0) { + gusb_list_units(); + exit (0); + } + if (0 == found_devices) { fatal("Found no Garmin USB devices.\n"); } } -#endif /* !defined(NO_USB) */ +static gusb_llops_t libusb_llops = { + gusb_libusb_get, + gusb_libusb_get_bulk, + gusb_libusb_send, + gusb_teardown +}; + +int +gusb_init(const char *portname, gpsdevh **dh) +{ + int req_unit_number = 0; + libusb_unit_data *lud = xcalloc(sizeof (libusb_unit_data), 1); + *dh = (gpsdevh*) lud; + +// usb_set_debug(99); + usb_init(); + gusb_register_ll(&libusb_llops); + + /* if "usb:N", read "N" to be the unit number. */ + if (strlen(portname) > 4) { + if (0 == strcmp(portname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(portname + 4); + } + } + + usb_find_busses(); + usb_find_devices(); + lud->busses = usb_get_busses(); + garmin_usb_scan(lud, req_unit_number); + + return 1; +} + +#endif /* HAVE_LIBUSB */ diff --git a/jeeps/gpsmath.c b/jeeps/gpsmath.c index e3a9284a7..45c48d822 100644 --- a/jeeps/gpsmath.c +++ b/jeeps/gpsmath.c @@ -158,7 +158,8 @@ void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s) *d = (int32)v; t = (v -(double)*d) * (double)60.0; - *s = (t-(double)*m) * (double)60.0; + *m = (v-(double)*d) * (double)60.0; + *s = (t - (int32)t) * (double)60.0; if(*s>(double)59.999) { @@ -250,7 +251,7 @@ double GPS_Math_Feet_To_Metres(double v) int32 GPS_Math_Deg_To_Semi(double v) { - return ((1U<<31) / 180) * v; + return ( (double)(1U<<31) / (double)180) * v; } @@ -266,7 +267,7 @@ int32 GPS_Math_Deg_To_Semi(double v) double GPS_Math_Semi_To_Deg(int32 v) { - return (double) (((double)v/(double)(1U<<31)) * (double)180); + return (double) (((double)v / (double)(1U<<31)) * (double)180); } @@ -1797,3 +1798,21 @@ int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, return 1; } + +int32 GPS_Lookup_Datum_Index(const char *n) +{ + GPS_PDatum dp; + const char *name; + + if (case_ignore_strcmp(n, "WGS84") == 0) name = "WGS 84"; + else if (case_ignore_strcmp(n, "WGS72") == 0) name = "WGS 72"; + else name = n; + + for (dp = GPS_Datum; dp->name; dp++) { + if (0 == case_ignore_strcmp(dp->name, name)) { + return dp - GPS_Datum; + } + } + + return -1; +} diff --git a/jeeps/gpsmath.h b/jeeps/gpsmath.h index 4e2249f08..e308b8514 100644 --- a/jeeps/gpsmath.h +++ b/jeeps/gpsmath.h @@ -116,6 +116,8 @@ int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, double N, int32 zone, char zc); +int32 GPS_Lookup_Datum_Index(const char *n); + #endif #ifdef __cplusplus diff --git a/jeeps/gpsmem.c b/jeeps/gpsmem.c index f5a893459..5bfe84afa 100644 --- a/jeeps/gpsmem.c +++ b/jeeps/gpsmem.c @@ -5,6 +5,7 @@ ** @version 1.0 ** @modified December 28th 1999 Alan Bleasby. First version ** @modified June 29th 2000 Alan Bleasby. NMEA additions +** @modified Copyright (C) 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -23,7 +24,6 @@ ** Boston, MA 02111-1307, USA. ********************************************************************/ #include "gps.h" -#include "garminusb.h" #include #include #include @@ -40,7 +40,7 @@ GPS_PPacket GPS_Packet_New(void) { GPS_PPacket ret; int hdr_size = sizeof(GPS_OPacket) ; - if(!(ret=(GPS_PPacket )malloc(hdr_size))) + if(!(ret=(GPS_PPacket )calloc(1, hdr_size))) { perror("malloc"); @@ -48,7 +48,7 @@ GPS_PPacket GPS_Packet_New(void) fflush(stderr); return NULL; } - if(!(ret->data = (UC *)malloc(MAX_GPS_PACKET_SIZE*sizeof(UC)))) + if(!(ret->data = (UC *)calloc(1, MAX_GPS_PACKET_SIZE*sizeof(UC)))) { perror("malloc"); fprintf(stderr,"GPS_Packet_New: Insufficient data memory"); @@ -63,7 +63,6 @@ GPS_PPacket GPS_Packet_New(void) } - /* @func GPS_Packet_Del *********************************************** ** ** Packet destructor @@ -94,7 +93,7 @@ GPS_PPvt_Data GPS_Pvt_New(void) { GPS_PPvt_Data ret; - if(!(ret=(GPS_PPvt_Data)malloc(sizeof(GPS_OPvt_Data)))) + if(!(ret=(GPS_PPvt_Data)calloc(1, sizeof(GPS_OPvt_Data)))) { perror("malloc"); fprintf(stderr,"GPS_Pvt_New: Insufficient memory"); @@ -136,7 +135,7 @@ GPS_PAlmanac GPS_Almanac_New(void) { GPS_PAlmanac ret; - if(!(ret=(GPS_PAlmanac)malloc(sizeof(GPS_OAlmanac)))) + if(!(ret=(GPS_PAlmanac)calloc(1, sizeof(GPS_OAlmanac)))) { perror("malloc"); fprintf(stderr,"GPS_Almanac_New: Insufficient memory"); @@ -301,1184 +300,3 @@ void GPS_Way_Del(GPS_PWay *thys) return; } - - - -/* @func GPS_Gsv_New *********************************************** -** -** Satellites in view constructor -** -** @return [GPS_PGsv] virgin siv -**********************************************************************/ - -GPS_PGsv GPS_Gsv_New(void) -{ - GPS_PGsv ret; - - if(!(ret=(GPS_PGsv)malloc(sizeof(GPS_OGsv)))) - return NULL; - - ret->valid = ret->inview = 0; - *ret->elevation = *ret->azimuth = *ret->strength = '\0'; - - return ret; -} - - - -/* @func GPS_Gsv_Del *********************************************** -** -** Satellites in view destructor -** -** @param [w] thys [GPS_PGsv *] siv to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Gsv_Del(GPS_PGsv *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Rme_New *********************************************** -** -** Position error constructor -** -** @return [GPS_PRme] virgin rme -**********************************************************************/ - -GPS_PRme GPS_Rme_New(void) -{ - GPS_PRme ret; - - if(!(ret=(GPS_PRme)malloc(sizeof(GPS_ORme)))) - return NULL; - - ret->valid = 0; - ret->hpe = ret->vpe = ret->spe = (double)0.; - - return ret; -} - - - -/* @func GPS_Rme_Del *********************************************** -** -** Position error destructor -** -** @param [w] thys [GPS_PRme *] posn error to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Rme_Del(GPS_PRme *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Wpl_New *********************************************** -** -** Waypoint constructor -** -** @return [GPS_PWpl] virgin rme -**********************************************************************/ - -GPS_PWpl GPS_Wpl_New(void) -{ - GPS_PWpl ret; - - if(!(ret=(GPS_PWpl)malloc(sizeof(GPS_OWpl)))) - return NULL; - - ret->valid = 0; - *ret->wpt = '\0'; - ret->lat = ret->lon = (double)0.; - - return ret; -} - - - -/* @func GPS_Wpl_Del *********************************************** -** -** Waypoint destructor -** -** @param [w] thys [GPS_PWpl *] waypoint to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Wpl_Del(GPS_PWpl *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Gll_New *********************************************** -** -** Position (geographic lat/lon) constructor -** -** @return [GPS_PGll] virgin gll -**********************************************************************/ - -GPS_PGll GPS_Gll_New(void) -{ - GPS_PGll ret; - - if(!(ret=(GPS_PGll)malloc(sizeof(GPS_OGll)))) - return NULL; - - ret->valid = 0; - ret->time = (time_t)0; - ret->lat = ret->lon = (double)0.; - ret->dv='\0'; - - return ret; -} - - - -/* @func GPS_Gll_Del *********************************************** -** -** Position destructor -** -** @param [w] thys [GPS_PGll *] posn to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Gll_Del(GPS_PGll *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Rmz_New *********************************************** -** -** Altitude constructor -** -** @return [GPS_PRmz] virgin altitude -**********************************************************************/ - -GPS_PRmz GPS_Rmz_New(void) -{ - GPS_PRmz ret; - - if(!(ret=(GPS_PRmz)malloc(sizeof(GPS_ORmz)))) - return NULL; - - ret->valid = ret->dim = ret->height = 0; - - return ret; -} - - - -/* @func GPS_Rmz_Del *********************************************** -** -** Altitude destructor -** -** @param [w] thys [GPS_PRmz *] altitude to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Rmz_Del(GPS_PRmz *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Rmm_New *********************************************** -** -** Datum constructor -** -** @return [GPS_PRmm] virgin datum -**********************************************************************/ - -GPS_PRmm GPS_Rmm_New(void) -{ - GPS_PRmm ret; - - if(!(ret=(GPS_PRmm)malloc(sizeof(GPS_ORmm)))) - return NULL; - - ret->valid = 0; - *ret->datum = '\0'; - - return ret; -} - - - -/* @func GPS_Rmm_Del *********************************************** -** -** Datum destructor -** -** @param [w] thys [GPS_PRmm *] datum to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Rmm_Del(GPS_PRmm *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Bod_New *********************************************** -** -** Bearing constructor -** -** @return [GPS_PBod] virgin bearing -**********************************************************************/ - -GPS_PBod GPS_Bod_New(void) -{ - GPS_PBod ret; - - if(!(ret=(GPS_PBod)malloc(sizeof(GPS_OBod)))) - return NULL; - - ret->valid = 0; - *ret->dest = *ret->start = '\0'; - ret->True = ret->mag = (double)0.; - - return ret; -} - - - -/* @func GPS_Bod_Del *********************************************** -** -** Bearing destructor -** -** @param [w] thys [GPS_PBod *] bearing to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Bod_Del(GPS_PBod *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Rte_New *********************************************** -** -** Route (NMEA) constructor -** -** @return [GPS_PRte] virgin bearing -**********************************************************************/ - -GPS_PRte GPS_Rte_New(void) -{ - GPS_PRte ret; - - if(!(ret=(GPS_PRte)malloc(sizeof(GPS_ORte)))) - return NULL; - - ret->valid = ret->rte = 0; - ret->type = '\0'; - ret->wpts = NULL; - - return ret; -} - - - -/* @func GPS_Rte_Del *********************************************** -** -** Route (NMEA) destructor -** -** @param [w] thys [GPS_PRte *] route to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Rte_Del(GPS_PRte *thys) -{ - if((*thys)->wpts) - free((void *)(*thys)->wpts); - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Rmc_New *********************************************** -** -** Minimum recommended specific constructor -** -** @return [GPS_PRmc] virgin minimum -**********************************************************************/ - -GPS_PRmc GPS_Rmc_New(void) -{ - GPS_PRmc ret; - - if(!(ret=(GPS_PRmc)malloc(sizeof(GPS_ORmc)))) - return NULL; - - ret->valid = 0; - ret->time = (time_t)0; - *ret->date = ret->warn = '\0'; - ret->lat = ret->lon = ret->speed = ret->cmg = ret->magvar = - (double)0.; - - return ret; -} - - - -/* @func GPS_Rmc_Del *********************************************** -** -** Minimum recommended specific destructor -** -** @param [w] thys [GPS_PRmc *] rec min to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Rmc_Del(GPS_PRmc *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Rmb_New *********************************************** -** -** Minimum recommended nav constructor -** -** @return [GPS_PRmb] virgin minimum nav -**********************************************************************/ - -GPS_PRmb GPS_Rmb_New(void) -{ - GPS_PRmb ret; - - if(!(ret=(GPS_PRmb)malloc(sizeof(GPS_ORmb)))) - return NULL; - - ret->valid = 0; - *ret->owpt = *ret->dwpt = ret->warn = ret->correct = ret->alarm = '\0'; - ret->cross = ret->lat = ret->lon = ret->range = ret->True = ret->velocity = - (double)0.; - - return ret; -} - - - -/* @func GPS_Rmb_Del *********************************************** -** -** Minimum recommended nav destructor -** -** @param [w] thys [GPS_PRmb *] rec min nav to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Rmb_Del(GPS_PRmb *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Gga_New *********************************************** -** -** Fix constructor -** -** @return [GPS_PGga] virgin fix -**********************************************************************/ - -GPS_PGga GPS_Gga_New(void) -{ - GPS_PGga ret; - - if(!(ret=(GPS_PGga)malloc(sizeof(GPS_OGga)))) - return NULL; - - ret->time = (time_t)0.; - ret->valid = ret->qual = ret->nsat = ret->last = ret->dgpsid = 0; - ret->hdil = ret->lat = ret->lon = ret->alt = ret->galt = (double)0.; - - return ret; -} - - - -/* @func GPS_Gga_Del *********************************************** -** -** Fix destructor -** -** @param [w] thys [GPS_PGga *] fix to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Gga_Del(GPS_PGga *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Gsa_New *********************************************** -** -** DOP constructor -** -** @return [GPS_PGsa] virgin DOP -**********************************************************************/ - -GPS_PGsa GPS_Gsa_New(void) -{ - GPS_PGsa ret; - - if(!(ret=(GPS_PGsa)malloc(sizeof(GPS_OGsa)))) - return NULL; - - ret->type = '\0'; - ret->valid = ret->nsat = ret->fix = 0; - ret->pdop = ret->hdop = ret->vdop = (double)0.; - - return ret; -} - - - -/* @func GPS_Gsa_Del *********************************************** -** -** DOP destructor -** -** @param [w] thys [GPS_PGsa *] DOP to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Gsa_Del(GPS_PGsa *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Apb_New *********************************************** -** -** Autopilot B constructor -** -** @return [GPS_PApb] virgin autopilot -**********************************************************************/ - -GPS_PApb GPS_Apb_New(void) -{ - GPS_PApb ret; - - if(!(ret=(GPS_PApb)malloc(sizeof(GPS_OApb)))) - return NULL; - - ret->blink = ret->warn = ret->steer = ret->unit = ret->alarmc = - ret->alarmp = *ret->wpt = '\0'; - ret->valid = 0; - ret->edist = ret->od = ret->pd = ret->hdg = (double)0.; - - return ret; -} - - - -/* @func GPS_Apb_Del *********************************************** -** -** Autopilot destructor -** -** @param [w] thys [GPS_PApb *] autopilot to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Apb_Del(GPS_PApb *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Bwc_New *********************************************** -** -** Waypoint bng constructor -** -** @return [GPS_PBwc] virgin waypoint bng -**********************************************************************/ - -GPS_PBwc GPS_Bwc_New(void) -{ - GPS_PBwc ret; - - if(!(ret=(GPS_PBwc)malloc(sizeof(GPS_OBwc)))) - return NULL; - - *ret->wpt = '\0'; - ret->time = (time_t)0; - ret->valid = 0; - ret->lat = ret->lon = ret->True = ret->mag = ret->dist = (double)0.; - - return ret; -} - - - -/* @func GPS_Bwc_Del *********************************************** -** -** Waypoint bearing destructor -** -** @param [w] thys [GPS_PBwc *] waypoint bearing to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Bwc_Del(GPS_PBwc *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Bwr_New *********************************************** -** -** Waypoint bng rhumb constructor -** -** @return [GPS_PBwr] virgin waypoint bng -**********************************************************************/ - -GPS_PBwr GPS_Bwr_New(void) -{ - GPS_PBwr ret; - - if(!(ret=(GPS_PBwr)malloc(sizeof(GPS_OBwr)))) - return NULL; - - *ret->wpt = '\0'; - ret->time = (time_t)0; - ret->valid = 0; - ret->lat = ret->lon = ret->True = ret->mag = ret->dist = (double)0.; - - return ret; -} - - - -/* @func GPS_Bwr_Del *********************************************** -** -** Waypoint bearing rhumb destructor -** -** @param [w] thys [GPS_PBwr *] waypoint bearing rhumb to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Bwr_Del(GPS_PBwr *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Dbt_New *********************************************** -** -** Depth constructor -** -** @return [GPS_PDbt] virgin depth -**********************************************************************/ - -GPS_PDbt GPS_Dbt_New(void) -{ - GPS_PDbt ret; - - if(!(ret=(GPS_PDbt)malloc(sizeof(GPS_ODbt)))) - return NULL; - - ret->valid = 0; - ret->f = ret->m = (double)0.; - - return ret; -} - - - -/* @func GPS_Dbt_Del *********************************************** -** -** Depth destructor -** -** @param [w] thys [GPS_PDbt *] depth to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Dbt_Del(GPS_PDbt *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Hdm_New *********************************************** -** -** Magnetic heading constructor -** -** @return [GPS_PHdm] virgin hdg -**********************************************************************/ - -GPS_PHdm GPS_Hdm_New(void) -{ - GPS_PHdm ret; - - if(!(ret=(GPS_PHdm)malloc(sizeof(GPS_OHdm)))) - return NULL; - - ret->valid = 0; - ret->hdg = (double)0.; - - return ret; -} - - - -/* @func GPS_Hdm_Del *********************************************** -** -** Magnetic heading destructor -** -** @param [w] thys [GPS_PHdm *] mag hdg to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Hdm_Del(GPS_PHdm *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Hsc_New *********************************************** -** -** Heading to steer constructor -** -** @return [GPS_PHsc] virgin hdg -**********************************************************************/ - -GPS_PHsc GPS_Hsc_New(void) -{ - GPS_PHsc ret; - - if(!(ret=(GPS_PHsc)malloc(sizeof(GPS_OHsc)))) - return NULL; - - ret->valid = 0; - ret->True = ret->mag = (double)0.; - - return ret; -} - - - -/* @func GPS_Hsc_Del *********************************************** -** -** Heading to steer destructor -** -** @param [w] thys [GPS_PHsc *] hdg to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Hsc_Del(GPS_PHsc *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Mtw_New *********************************************** -** -** Water temp constructor -** -** @return [GPS_PMtw] virgin temp -**********************************************************************/ - -GPS_PMtw GPS_Mtw_New(void) -{ - GPS_PMtw ret; - - if(!(ret=(GPS_PMtw)malloc(sizeof(GPS_OMtw)))) - return NULL; - - ret->valid = 0; - ret->T = (double)0.; - - return ret; -} - - - -/* @func GPS_Mtw_Del *********************************************** -** -** Water temperature destructor -** -** @param [w] thys [GPS_PMtw *] water temp to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Mtw_Del(GPS_PMtw *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_R00_New *********************************************** -** -** Waypoint list constructor -** -** @return [GPS_PR00] virgin wpt list -**********************************************************************/ - -GPS_PR00 GPS_R00_New(void) -{ - GPS_PR00 ret; - - if(!(ret=(GPS_PR00)malloc(sizeof(GPS_OR00)))) - return NULL; - - ret->valid = 0; - *ret->wpts='\0'; - - return ret; -} - - - -/* @func GPS_R00_Del *********************************************** -** -** Waypoint list destructor -** -** @param [w] thys [GPS_PR00 *] waypoint list to delete -** -** @return [void] -**********************************************************************/ - -void GPS_R00_Del(GPS_PR00 *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Vhw_New *********************************************** -** -** Water speed constructor -** -** @return [GPS_PVhw] virgin water speed -**********************************************************************/ - -GPS_PVhw GPS_Vhw_New(void) -{ - GPS_PVhw ret; - - if(!(ret=(GPS_PVhw)malloc(sizeof(GPS_OVhw)))) - return NULL; - - ret->valid = 0; - ret->True = ret->mag = ret->wspeed = ret->speed = (double)0.; - - return ret; -} - - - -/* @func GPS_Vhw_Del *********************************************** -** -** Water speed destructor -** -** @param [w] thys [GPS_PVhw *] waypoint list to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Vhw_Del(GPS_PVhw *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Vwr_New *********************************************** -** -** Wind constructor -** -** @return [GPS_PVwr] virgin wind -**********************************************************************/ - -GPS_PVwr GPS_Vwr_New(void) -{ - GPS_PVwr ret; - - if(!(ret=(GPS_PVwr)malloc(sizeof(GPS_OVwr)))) - return NULL; - - ret->wdir = '\0'; - ret->valid = 0; - ret->wind = ret->knots = ret->ms = ret->khr = (double)0.; - - return ret; -} - - - -/* @func GPS_Vwr_Del *********************************************** -** -** Wind destructor -** -** @param [w] thys [GPS_PVwr *] wind to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Vwr_Del(GPS_PVwr *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Vtg_New *********************************************** -** -** Track made good constructor -** -** @return [GPS_PVtg] virgin tmg -**********************************************************************/ - -GPS_PVtg GPS_Vtg_New(void) -{ - GPS_PVtg ret; - - if(!(ret=(GPS_PVtg)malloc(sizeof(GPS_OVtg)))) - return NULL; - - ret->valid = 0; - ret->True = ret->mag = ret->knots = ret->khr = (double)0.; - - return ret; -} - - - -/* @func GPS_Vtg_Del *********************************************** -** -** Track made good destructor -** -** @param [w] thys [GPS_PVtg *] tmg to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Vtg_Del(GPS_PVtg *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Xte_New *********************************************** -** -** Cross track error constructor -** -** @return [GPS_Xte] virgin xte -**********************************************************************/ - -GPS_PXte GPS_Xte_New(void) -{ - GPS_PXte ret; - - if(!(ret=(GPS_PXte)malloc(sizeof(GPS_OXte)))) - return NULL; - - ret->valid = 0; - ret->warn = ret->cycle = ret->steer = ret->unit = '\0'; - ret->dist = (double)0.; - - return ret; -} - - - -/* @func GPS_Xte_Del *********************************************** -** -** Cross track error destructor -** -** @param [w] thys [GPS_PXte *] xte to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Xte_Del(GPS_PXte *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Xtr_New *********************************************** -** -** Cross track error dead constructor -** -** @return [GPS_Xtr] virgin xtr -**********************************************************************/ - -GPS_PXtr GPS_Xtr_New(void) -{ - GPS_PXtr ret; - - if(!(ret=(GPS_PXtr)malloc(sizeof(GPS_OXtr)))) - return NULL; - - ret->valid = 0; - ret->steer = ret->unit = '\0'; - ret->dist = (double)0.; - - return ret; -} - - - -/* @func GPS_Xtr_Del *********************************************** -** -** Cross track error dead destructor -** -** @param [w] thys [GPS_PXtr *] xtr to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Xtr_Del(GPS_PXtr *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Lib_New *********************************************** -** -** Link constructor -** -** @return [GPS_Lib] virgin link -**********************************************************************/ - -GPS_PLib GPS_Lib_New(void) -{ - GPS_PLib ret; - - if(!(ret=(GPS_PLib)malloc(sizeof(GPS_OLib)))) - return NULL; - - ret->valid = 0; - ret->rqst = '\0'; - ret->freq = ret->baud = (double)0.; - - return ret; -} - - - -/* @func GPS_Lib_Del *********************************************** -** -** Link destructor -** -** @param [w] thys [GPS_PLib *] link to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Lib_Del(GPS_PLib *thys) -{ - free((void *)*thys); - - return; -} - - - - -/* @func GPS_Nmea_New *********************************************** -** -** Nmea data constructor -** -** @return [GPS_PNmea] virgin nmea data -**********************************************************************/ - -GPS_PNmea GPS_Nmea_New(void) -{ - GPS_PNmea ret; - - if(!(ret=(GPS_PNmea)malloc(sizeof(GPS_ONmea)))) - return NULL; - - ret->gsv = GPS_Gsv_New(); - ret->rme = GPS_Rme_New(); - ret->gll = GPS_Gll_New(); - ret->rmz = GPS_Rmz_New(); - ret->rmm = GPS_Rmm_New(); - ret->bod = GPS_Bod_New(); - ret->rte = GPS_Rte_New(); - ret->wpl = GPS_Wpl_New(); - ret->rmc = GPS_Rmc_New(); - ret->rmb = GPS_Rmb_New(); - ret->gga = GPS_Gga_New(); - ret->gsa = GPS_Gsa_New(); - ret->apb = GPS_Apb_New(); - ret->bwc = GPS_Bwc_New(); - ret->bwr = GPS_Bwr_New(); - ret->dbt = GPS_Dbt_New(); - ret->hdm = GPS_Hdm_New(); - ret->hsc = GPS_Hsc_New(); - ret->mtw = GPS_Mtw_New(); - ret->r00 = GPS_R00_New(); - ret->vhw = GPS_Vhw_New(); - ret->vwr = GPS_Vwr_New(); - ret->vtg = GPS_Vtg_New(); - ret->xte = GPS_Xte_New(); - ret->xtr = GPS_Xtr_New(); - ret->lib = GPS_Lib_New(); - - return ret; -} - - - -/* @func GPS_Nmea_Del *********************************************** -** -** NMEA data destructor -** -** @param [w] thys [GPS_PNmea *] nmea data to delete -** -** @return [void] -**********************************************************************/ - -void GPS_Nmea_Del(GPS_PNmea *thys) -{ - - GPS_Gsv_Del(&(*thys)->gsv); - GPS_Rme_Del(&(*thys)->rme); - GPS_Gll_Del(&(*thys)->gll); - GPS_Rmz_Del(&(*thys)->rmz); - GPS_Rmm_Del(&(*thys)->rmm); - GPS_Bod_Del(&(*thys)->bod); - GPS_Rte_Del(&(*thys)->rte); - GPS_Wpl_Del(&(*thys)->wpl); - GPS_Rmc_Del(&(*thys)->rmc); - GPS_Rmb_Del(&(*thys)->rmb); - GPS_Gga_Del(&(*thys)->gga); - GPS_Gsa_Del(&(*thys)->gsa); - GPS_Apb_Del(&(*thys)->apb); - GPS_Bwc_Del(&(*thys)->bwc); - GPS_Bwr_Del(&(*thys)->bwr); - GPS_Dbt_Del(&(*thys)->dbt); - GPS_Hdm_Del(&(*thys)->hdm); - GPS_Hsc_Del(&(*thys)->hsc); - GPS_Mtw_Del(&(*thys)->mtw); - GPS_R00_Del(&(*thys)->r00); - GPS_Vhw_Del(&(*thys)->vhw); - GPS_Vwr_Del(&(*thys)->vwr); - GPS_Vtg_Del(&(*thys)->vtg); - GPS_Xte_Del(&(*thys)->xte); - GPS_Xtr_Del(&(*thys)->xtr); - GPS_Lib_Del(&(*thys)->lib); - - free((void *)*thys); - - return; -} diff --git a/jeeps/gpsmem.h b/jeeps/gpsmem.h index 8a52fad2e..f4e5f505d 100644 --- a/jeeps/gpsmem.h +++ b/jeeps/gpsmem.h @@ -20,67 +20,6 @@ void GPS_Track_Del(GPS_PTrack *thys); GPS_PWay GPS_Way_New(void); void GPS_Way_Del(GPS_PWay *thys); - -/* - * NMEA Section - */ -GPS_PGsv GPS_Gsv_New(void); -void GPS_Gsv_Del(GPS_PGsv *thys); -GPS_PRme GPS_Rme_New(void); -void GPS_Rme_Del(GPS_PRme *thys); -GPS_PGll GPS_Gll_New(void); -void GPS_Gll_Del(GPS_PGll *thys); -GPS_PRmz GPS_Rmz_New(void); -void GPS_Rmz_Del(GPS_PRmz *thys); -GPS_PRmm GPS_Rmm_New(void); -void GPS_Rmm_Del(GPS_PRmm *thys); -GPS_PBod GPS_Bod_New(void); -void GPS_Bod_Del(GPS_PBod *thys); -GPS_PRte GPS_Rte_New(void); -void GPS_Rte_Del(GPS_PRte *thys); -GPS_PRmc GPS_Rmc_New(void); -void GPS_Rmc_Del(GPS_PRmc *thys); -GPS_PRmb GPS_Rmb_New(void); -void GPS_Rmb_Del(GPS_PRmb *thys); -GPS_PGga GPS_Gga_New(void); -void GPS_Gga_Del(GPS_PGga *thys); -GPS_PGsa GPS_Gsa_New(void); -void GPS_Gsa_Del(GPS_PGsa *thys); -GPS_PApb GPS_Apb_New(void); -void GPS_Apb_Del(GPS_PApb *thys); -GPS_PBwc GPS_Bwc_New(void); -void GPS_Bwc_Del(GPS_PBwc *thys); -GPS_PBwr GPS_Bwr_New(void); -void GPS_Bwr_Del(GPS_PBwr *thys); -GPS_PDbt GPS_Dbt_New(void); -void GPS_Dbt_Del(GPS_PDbt *thys); -GPS_PHdm GPS_Hdm_New(void); -void GPS_Hdm_Del(GPS_PHdm *thys); -GPS_PHsc GPS_Hsc_New(void); -void GPS_Hsc_Del(GPS_PHsc *thys); -GPS_PMtw GPS_Mtw_New(void); -void GPS_Mtw_Del(GPS_PMtw *thys); -GPS_PR00 GPS_R00_New(void); -void GPS_R00_Del(GPS_PR00 *thys); -GPS_PVhw GPS_Vhw_New(void); -void GPS_Vhw_Del(GPS_PVhw *thys); -GPS_PVwr GPS_Vwr_New(void); -void GPS_Vwr_Del(GPS_PVwr *thys); -GPS_PVtg GPS_Vtg_New(void); -void GPS_Vtg_Del(GPS_PVtg *thys); -GPS_PXte GPS_Xte_New(void); -void GPS_Xte_Del(GPS_PXte *thys); -GPS_PXtr GPS_Xtr_New(void); -void GPS_Xtr_Del(GPS_PXtr *thys); -GPS_PLib GPS_Lib_New(void); -void GPS_Lib_Del(GPS_PLib *thys); -GPS_PWpl GPS_Wpl_New(void); -void GPS_Wpl_Del(GPS_PWpl *thys); -GPS_PNmea GPS_Nmea_New(void); -void GPS_Nmea_Del(GPS_PNmea *thys); - - - #endif #ifdef __cplusplus diff --git a/jeeps/gpsnmea.h b/jeeps/gpsnmea.h deleted file mode 100644 index 53255c65a..000000000 --- a/jeeps/gpsnmea.h +++ /dev/null @@ -1,312 +0,0 @@ -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef gpsnmea_h -#define gpsnmea_h - - -#include "gps.h" - - -typedef struct GPS_SGsv -{ - int32 inview; - int32 prn[32]; - int32 elevation[32]; - int32 azimuth[32]; - int32 strength[32]; - int32 valid; -} GPS_OGsv,*GPS_PGsv; - -typedef struct GPS_SRme -{ - double hpe; - double vpe; - double spe; - int32 valid; -} GPS_ORme,*GPS_PRme; - -typedef struct GPS_SGll -{ - double lat; - double lon; - time_t time; - char dv; - int32 valid; -} GPS_OGll,*GPS_PGll; - -typedef struct GPS_SRmz -{ - int32 height; - int32 dim; - int32 valid; -} GPS_ORmz,*GPS_PRmz; - -typedef struct GPS_SRmm -{ - char datum[83]; - int32 valid; -} GPS_ORmm,*GPS_PRmm; - -typedef struct GPS_SBod -{ - double True; - double mag; - char dest[83]; - char start[83]; - int32 valid; -} GPS_OBod,*GPS_PBod; - -typedef struct GPS_SRte -{ - char type; - int32 rte; - char *wpts; - int32 valid; -} GPS_ORte,*GPS_PRte; - -typedef struct GPS_SWpl -{ - double lat; - double lon; - char wpt[83]; - int32 valid; -} GPS_OWpl,*GPS_PWpl; - -typedef struct GPS_SRmc -{ - time_t time; - char warn; - double lat; - double lon; - double speed; - double cmg; - char date[83]; - double magvar; - int32 valid; -} GPS_ORmc,*GPS_PRmc; - -typedef struct GPS_SRmb -{ - char warn; - double cross; - char correct; - char owpt[83]; - char dwpt[83]; - double lat; - double lon; - double range; - double True; - double velocity; - char alarm; - int32 valid; -} GPS_ORmb,*GPS_PRmb; - -typedef struct GPS_SGga -{ - time_t time; - double lat; - double lon; - int32 qual; - int32 nsat; - double hdil; - double alt; - double galt; - int32 last; - int32 dgpsid; - int32 valid; -} GPS_OGga,*GPS_PGga; - -typedef struct GPS_SGsa -{ - char type; - int32 fix; - int32 nsat; - int32 prn[12]; - double pdop; - double hdop; - double vdop; - int32 valid; -} GPS_OGsa,*GPS_PGsa; - -typedef struct GPS_SApb -{ - char blink; - char warn; - double edist; - char steer; - char unit; - char alarmc; - char alarmp; - double od; - char wpt[83]; - double pd; - double hdg; - int32 valid; -} GPS_OApb,*GPS_PApb; - -typedef struct GPS_SBwc -{ - time_t time; - double lat; - double lon; - double True; - double mag; - double dist; - char wpt[83]; - int32 valid; -} GPS_OBwc,*GPS_PBwc; - -typedef struct GPS_SBwr -{ - time_t time; - double lat; - double lon; - double True; - double mag; - double dist; - char wpt[83]; - int32 valid; -} GPS_OBwr,*GPS_PBwr; - -typedef struct GPS_SDbt -{ - double f; - double m; - int32 valid; -} GPS_ODbt,*GPS_PDbt; - -typedef struct GPS_SHdm -{ - double hdg; - int32 valid; -} GPS_OHdm,*GPS_PHdm; - -typedef struct GPS_SHsc -{ - double True; - double mag; - int32 valid; -} GPS_OHsc,*GPS_PHsc; - -typedef struct GPS_SMtw -{ - double T; - int32 valid; -} GPS_OMtw,*GPS_PMtw; - -typedef struct GPS_SR00 -{ - char wpts[83]; - int32 valid; -} GPS_OR00,*GPS_PR00; - -typedef struct GPS_SVhw -{ - double True; - double mag; - double wspeed; - double speed; - int32 valid; -} GPS_OVhw,*GPS_PVhw; - -typedef struct GPS_SVwr -{ - double wind; - char wdir; - double knots; - double ms; - double khr; - int32 valid; -} GPS_OVwr,*GPS_PVwr; - -typedef struct GPS_SVtg -{ - double True; - double mag; - double knots; - double khr; - int32 valid; -} GPS_OVtg,*GPS_PVtg; - -typedef struct GPS_SXte -{ - char warn; - char cycle; - double dist; - char steer; - char unit; - int32 valid; -} GPS_OXte,*GPS_PXte; - -typedef struct GPS_SXtr -{ - double dist; - char steer; - char unit; - int32 valid; -} GPS_OXtr,*GPS_PXtr; - -typedef struct GPS_SLib -{ - double freq; - double baud; - char rqst; - int32 valid; -} GPS_OLib,*GPS_PLib; - - -typedef struct GPS_SNmea -{ - GPS_PGsv gsv; - GPS_PRme rme; - GPS_PGll gll; - GPS_PRmz rmz; - GPS_PRmm rmm; - GPS_PBod bod; - GPS_PRte rte; - GPS_PWpl wpl; - GPS_PRmc rmc; - GPS_PRmb rmb; - GPS_PGga gga; - GPS_PGsa gsa; - GPS_PApb apb; - GPS_PBwc bwc; - GPS_PBwr bwr; - GPS_PDbt dbt; - GPS_PHdm hdm; - GPS_PHsc hsc; - GPS_PMtw mtw; - GPS_PR00 r00; - GPS_PVhw vhw; - GPS_PVwr vwr; - GPS_PVtg vtg; - GPS_PXte xte; - GPS_PXtr xtr; - GPS_PLib lib; -} GPS_ONmea,*GPS_PNmea; - - - - - - -extern int32 gps_fd; /* FD for serial port access [NMEA] */ -extern GPS_PNmea gps_nmea; /* Internal nmea data repository */ - - - -void GPS_NMEA_Add_Checksum(char *s); -int32 GPS_NMEA_Line_Check(const char *s); -int32 GPS_NMEA_Load(int32 fd); -int32 GPS_NMEA_Init(const char *s); -void GPS_NMEA_Exit(void); -int32 GPS_NMEA_Send(const char *s, int32 flag); - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/jeeps/gpsnmeafmt.h b/jeeps/gpsnmeafmt.h deleted file mode 100644 index 91d38041c..000000000 --- a/jeeps/gpsnmeafmt.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef gpsnmeafmt_h -#define gpsnmeafmt_h - - -#include "gps.h" - -int32 GPS_NMEA_Apb_Scan(const char *s, GPS_PApb *thys); -int32 GPS_NMEA_Bod_Scan(const char *s, GPS_PBod *thys); -int32 GPS_NMEA_Bwc_Scan(const char *s, GPS_PBwc *thys); -int32 GPS_NMEA_Bwr_Scan(const char *s, GPS_PBwr *thys); -int32 GPS_NMEA_Dbt_Scan(const char *s, GPS_PDbt *thys); -int32 GPS_NMEA_Gga_Scan(const char *s, GPS_PGga *thys); -int32 GPS_NMEA_Gll_Scan(const char *s, GPS_PGll *thys); -int32 GPS_NMEA_Gsa_Scan(const char *s, GPS_PGsa *thys); -int32 GPS_NMEA_Gsv_Scan(const char *s, GPS_PGsv *thys); -int32 GPS_NMEA_Hdm_Scan(const char *s, GPS_PHdm *thys); -int32 GPS_NMEA_Hsc_Scan(const char *s, GPS_PHsc *thys); -int32 GPS_NMEA_Mtw_Scan(const char *s, GPS_PMtw *thys); -int32 GPS_NMEA_R00_Scan(const char *s, GPS_PR00 *thys); -int32 GPS_NMEA_Rmb_Scan(const char *s, GPS_PRmb *thys); -int32 GPS_NMEA_Rmc_Scan(const char *s, GPS_PRmc *thys); -int32 GPS_NMEA_Rte_Scan(const char *s, GPS_PRte *thys); -int32 GPS_NMEA_Vhw_Scan(const char *s, GPS_PVhw *thys); -int32 GPS_NMEA_Vwr_Scan(const char *s, GPS_PVwr *thys); -int32 GPS_NMEA_Vtg_Scan(const char *s, GPS_PVtg *thys); -int32 GPS_NMEA_Wpl_Scan(const char *s, GPS_PWpl *thys); -int32 GPS_NMEA_Xte_Scan(const char *s, GPS_PXte *thys); -int32 GPS_NMEA_Xtr_Scan(const char *s, GPS_PXtr *thys); -int32 GPS_NMEA_Rme_Scan(const char *s, GPS_PRme *thys); -int32 GPS_NMEA_Rmz_Scan(const char *s, GPS_PRmz *thys); -int32 GPS_NMEA_Rmm_Scan(const char *s, GPS_PRmm *thys); -int32 GPS_NMEA_Lib_Scan(const char *s, GPS_PLib *thys); - - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/jeeps/gpsnmeaget.h b/jeeps/gpsnmeaget.h deleted file mode 100644 index 17cba4801..000000000 --- a/jeeps/gpsnmeaget.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef gpsnmearead_h -#define gpsnmearead_h - - -#include "gps.h" - -int32 GPS_NMEA_Get_Apb(GPS_PApb *thys); -int32 GPS_NMEA_Get_Bod(GPS_PBod *thys); -int32 GPS_NMEA_Get_Bwc(GPS_PBwc *thys); -int32 GPS_NMEA_Get_Bwr(GPS_PBwr *thys); -int32 GPS_NMEA_Get_Dbt(GPS_PDbt *thys); -int32 GPS_NMEA_Get_Gga(GPS_PGga *thys); -int32 GPS_NMEA_Get_Gll(GPS_PGll *thys); -int32 GPS_NMEA_Get_Gsa(GPS_PGsa *thys); -int32 GPS_NMEA_Get_Gsv(GPS_PGsv *thys); -int32 GPS_NMEA_Get_Hdm(GPS_PHdm *thys); -int32 GPS_NMEA_Get_Hsc(GPS_PHsc *thys); -int32 GPS_NMEA_Get_Mtw(GPS_PMtw *thys); -int32 GPS_NMEA_Get_R00(GPS_PR00 *thys); -int32 GPS_NMEA_Get_Rmb(GPS_PRmb *thys); -int32 GPS_NMEA_Get_Rmc(GPS_PRmc *thys); -int32 GPS_NMEA_Get_Rte(GPS_PRte *thys); -int32 GPS_NMEA_Get_Vhw(GPS_PVhw *thys); -int32 GPS_NMEA_Get_Vwr(GPS_PVwr *thys); -int32 GPS_NMEA_Get_Vtg(GPS_PVtg *thys); -int32 GPS_NMEA_Get_Wpl(GPS_PWpl *thys); -int32 GPS_NMEA_Get_Xte(GPS_PXte *thys); -int32 GPS_NMEA_Get_Xtr(GPS_PXtr *thys); -int32 GPS_NMEA_Get_Rme(GPS_PRme *thys); -int32 GPS_NMEA_Get_Rmz(GPS_PRmz *thys); -int32 GPS_NMEA_Get_Rmm(GPS_PRmm *thys); -int32 GPS_NMEA_Get_Lib(GPS_PLib *thys); - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/jeeps/gpsprot.c b/jeeps/gpsprot.c index 812437092..63976d995 100644 --- a/jeeps/gpsprot.c +++ b/jeeps/gpsprot.c @@ -4,6 +4,7 @@ ** @author Copyright (C) 1999 Alan Bleasby ** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -36,7 +37,7 @@ static int32 gps_n_tag_unknown = 0; struct COMMANDDATA COMMAND_ID[2]= { { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x31,0x32 + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x31,0x32,92,117,121,450 } , { diff --git a/jeeps/gpsprot.h b/jeeps/gpsprot.h index 1d0eb6a42..05ff71857 100644 --- a/jeeps/gpsprot.h +++ b/jeeps/gpsprot.h @@ -33,6 +33,7 @@ struct LINKDATA UC Pid_Protocol_Array; UC Pid_Product_Rqst; UC Pid_Product_Data; + UC Pid_Wpt_Cat_Data; } ; @@ -52,17 +53,21 @@ int32 gps_device_command; struct COMMANDDATA { - UC Cmnd_Abort_Transfer; - UC Cmnd_Transfer_Alm; - UC Cmnd_Transfer_Posn; - UC Cmnd_Transfer_Prx; - UC Cmnd_Transfer_Rte; - UC Cmnd_Transfer_Time; - UC Cmnd_Transfer_Trk; - UC Cmnd_Transfer_Wpt; - UC Cmnd_Turn_Off_Pwr; - UC Cmnd_Start_Pvt_Data; - UC Cmnd_Stop_Pvt_Data; + US Cmnd_Abort_Transfer; + US Cmnd_Transfer_Alm; + US Cmnd_Transfer_Posn; + US Cmnd_Transfer_Prx; + US Cmnd_Transfer_Rte; + US Cmnd_Transfer_Time; + US Cmnd_Transfer_Trk; + US Cmnd_Transfer_Wpt; + US Cmnd_Turn_Off_Pwr; + US Cmnd_Start_Pvt_Data; + US Cmnd_Stop_Pvt_Data; + US Cmnd_FlightBook_Transfer; + US Cmnd_Transfer_Lap; + US Cmnd_Transfer_Wpt_Cats; + US Cmnd_Transfer_Runs; } ; @@ -75,6 +80,11 @@ struct COMMANDDATA #define pA100 100 int32 gps_waypt_transfer; +/* + * Waypoint category transfer protocol + */ +#define pA101 101 +int32 gps_category_transfer; /* * Route Transfer Protocol @@ -89,6 +99,7 @@ int32 gps_route_transfer; #define pA300 300 #define pA301 301 #define pA302 302 +#define pA304 304 int32 gps_trk_transfer; /* @@ -124,7 +135,14 @@ int32 gps_position_transfer; #define pA800 800 int32 gps_pvt_transfer; +/* + * Lap Data Transfer + */ +#define pA906 906 +int32 gps_lap_transfer; +#define pA1000 1000 +int32 gps_run_transfer; @@ -151,6 +169,11 @@ int32 gps_pvt_transfer; int32 gps_rte_type; int32 gps_waypt_type; +/* + * Waypoint category types + */ +#define pD120 120 +int32 gps_category_type; /* * Rte Header Type @@ -175,6 +198,7 @@ int32 gps_rte_link_type; #define pD301 301 #define pD302 302 #define pD303 303 +#define pD304 304 int32 gps_trk_type; @@ -234,6 +258,12 @@ int32 gps_position_type; int32 gps_pvt_type; +/* + * Lap Data Type + */ +#define pD906 906 + +int32 gps_lap_type; /* * Link protocol type diff --git a/jeeps/gpsread.c b/jeeps/gpsread.c index 2d2f2d153..587f15c6f 100644 --- a/jeeps/gpsread.c +++ b/jeeps/gpsread.c @@ -4,6 +4,7 @@ ** @author Copyright (C) 1999 Alan Bleasby ** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -22,7 +23,7 @@ ** Boston, MA 02111-1307, USA. ********************************************************************/ #include "gps.h" -#include "gpsusbint.h" +#include "gpsserial.h" #include #include #include @@ -57,7 +58,7 @@ time_t GPS_Time_Now(void) -/* @func GPS_Packet_Read *********************************************** +/* @func GPS_Serial_Packet_Read *********************************************** ** ** Read a packet ** @@ -67,7 +68,7 @@ time_t GPS_Time_Now(void) ** @return [int32] number of bytes read **********************************************************************/ -int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet) +int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet) { time_t start; int32 n; @@ -84,10 +85,6 @@ int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet) isDLE = gpsFalse; p = (*packet)->data; - if (gps_is_usb) { - return GPS_Packet_Read_usb(fd, packet); - } - start = GPS_Time_Now(); GPS_Diag("Rx Data:"); while(GPS_Time_Now() < start+GPS_TIME_OUT) @@ -109,7 +106,7 @@ int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet) (*packet)->dle = u; if(u != DLE) { - (void) fprintf(stderr,"GPS_Packet_Read: No DLE\n"); + (void) fprintf(stderr,"GPS_Packet_Read: No DLE. Data received, but probably not a garmin packet.\n"); (void) fflush(stderr); return 0; } @@ -166,6 +163,14 @@ int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet) } m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2); + if (gps_show_bytes) { + GPS_Diag(" "); + for (i = 0; i < (*packet)->n; i++) { + char c = (*packet)->data[i]; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } + GPS_Diag(" "); + } GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); return (*packet)->n; } @@ -175,7 +180,7 @@ int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet) } - GPS_Error("GPS_Packet_Read: Time-out"); + GPS_Error("GPS_Packet_Read: Timeout. No data received."); gps_errno = SERIAL_ERROR; return 0; @@ -194,13 +199,9 @@ int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet) ** @return [int32] true if ACK **********************************************************************/ -int32 GPS_Get_Ack(int32 fd, GPS_PPacket *tra, GPS_PPacket *rec) +int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) { - if (gps_is_usb) { - return 1; - } - - if(!GPS_Packet_Read(fd, rec)) + if(!GPS_Serial_Packet_Read(fd, rec)) return 0; if(LINK_ID[0].Pid_Ack_Byte != (*rec)->type) diff --git a/jeeps/gpsread.h b/jeeps/gpsread.h index 5abd56cfa..17f3bd852 100644 --- a/jeeps/gpsread.h +++ b/jeeps/gpsread.h @@ -8,14 +8,10 @@ extern "C" #include "gps.h" -#include time_t GPS_Time_Now(void); -int32 GPS_Packet_Read(int32 fd, GPS_PPacket *packet); -int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet); -int32 GPS_Get_Ack(int32 fd, GPS_PPacket *tra, GPS_PPacket *rec); -int32 ajb(int32 fd); - +int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); +int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); #endif diff --git a/jeeps/gpsrqst.c b/jeeps/gpsrqst.c index 827559071..7203313c6 100644 --- a/jeeps/gpsrqst.c +++ b/jeeps/gpsrqst.c @@ -4,6 +4,7 @@ ** @author Copyright (C) 1999 Alan Bleasby ** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -24,8 +25,8 @@ #include "gps.h" -static int32 GPS_A600_Rqst(int32 fd, time_t Time); -static int32 GPS_A700_Rqst(int32 fd, double lat, double lon); +static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time); +static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); @@ -39,7 +40,7 @@ static int32 GPS_A700_Rqst(int32 fd, double lat, double lon); ** @return [int32] true if OK ************************************************************************/ -int32 GPS_Rqst_Send_Time(int32 fd, time_t Time) +int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time) { time_t ret=0; @@ -67,7 +68,7 @@ int32 GPS_Rqst_Send_Time(int32 fd, time_t Time) ** ** @return [int32] success ************************************************************************/ -static int32 GPS_A600_Rqst(int32 fd, time_t Time) +static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time) { GPS_PPacket tra; GPS_PPacket rec; @@ -110,7 +111,7 @@ static int32 GPS_A600_Rqst(int32 fd, time_t Time) ** @return [int32] success ************************************************************************/ -int32 GPS_Rqst_Send_Position(int32 fd, double lat, double lon) +int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon) { int32 ret=0; @@ -139,7 +140,7 @@ int32 GPS_Rqst_Send_Position(int32 fd, double lat, double lon) ** ** @return [int32] success ************************************************************************/ -static int32 GPS_A700_Rqst(int32 fd, double lat, double lon) +static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon) { GPS_PPacket tra; GPS_PPacket rec; diff --git a/jeeps/gpsrqst.h b/jeeps/gpsrqst.h index c6398ecd0..ec0169586 100644 --- a/jeeps/gpsrqst.h +++ b/jeeps/gpsrqst.h @@ -9,8 +9,8 @@ extern "C" #include "gps.h" -int32 GPS_Rqst_Send_Time(int32 fd, time_t Time); -int32 GPS_Rqst_Send_Position(int32 fd, double lat, double lon); +int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time); +int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon); #endif diff --git a/jeeps/gpssend.c b/jeeps/gpssend.c index b32ba2a27..d863683d9 100644 --- a/jeeps/gpssend.c +++ b/jeeps/gpssend.c @@ -4,6 +4,7 @@ ** @author Copyright (C) 1999 Alan Bleasby ** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version +** @modified Copyright (C) 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -22,7 +23,7 @@ ** Boston, MA 02111-1307, USA. ********************************************************************/ #include "gps.h" -#include "gpsusbint.h" +#include "gpsserial.h" #include #include @@ -41,7 +42,7 @@ ** @return [void] ************************************************************************/ -void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n) +void GPS_Serial_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n) { UC *p; UC *q; @@ -53,11 +54,6 @@ void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n) p = data; q = (*packet)->data; - if (gps_is_usb) { - GPS_Make_Packet_usb(packet, type, data, n); - return; - } - (*packet)->dle = DLE; (*packet)->edle = DLE; (*packet)->etx = ETX; @@ -130,13 +126,11 @@ DiagS(void *buf, size_t sz) ** @return [int32] number of bytes in the packet ************************************************************************/ -int32 GPS_Write_Packet(int32 fd, GPS_PPacket packet) +int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet) { size_t ret; const char *m1, *m2; - - if (gps_is_usb) - return GPS_Write_Packet_usb(fd, packet); + GPS_Diag("Tx Data:"); Diag(&packet->dle, 3); @@ -202,13 +196,10 @@ int32 GPS_Write_Packet(int32 fd, GPS_PPacket packet) ** @return [int32] success ************************************************************************/ -int32 GPS_Send_Ack(int32 fd, GPS_PPacket *tra, GPS_PPacket *rec) +int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) { UC data[2]; - if (gps_is_usb) - return 1; - GPS_Util_Put_Short(data,(US)(*rec)->type); GPS_Make_Packet(tra,LINK_ID[0].Pid_Ack_Byte,data,2); if(!GPS_Write_Packet(fd,*tra)) diff --git a/jeeps/gpssend.h b/jeeps/gpssend.h index f048fdec8..edd3f5b0d 100644 --- a/jeeps/gpssend.h +++ b/jeeps/gpssend.h @@ -11,12 +11,11 @@ extern "C" #define GPS_ARB_LEN 1024 -UC gps_sendbuf[GPS_ARB_LEN]; +void GPS_Serial_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n); +int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); void GPS_Make_Packet(GPS_PPacket *packet, UC type, UC *data, int16 n); -int32 GPS_Write_Packet(int32 fd, GPS_PPacket packet); -int32 GPS_Send_Ack(int32 fd, GPS_PPacket *tra, GPS_PPacket *rec); - #endif diff --git a/jeeps/gpsserial.c b/jeeps/gpsserial.c index 918423ade..78896bfe8 100644 --- a/jeeps/gpsserial.c +++ b/jeeps/gpsserial.c @@ -5,6 +5,7 @@ ** @version 1.0 ** @modified December 28th 1999 Alan Bleasby. First version ** @modified June 29th 2000 Alan Bleasby. NMEA additions +** @modified Copyright (C) 2006 Robert Lipe ** @@ ** ** This library is free software; you can redistribute it and/or @@ -23,7 +24,8 @@ ** Boston, MA 02111-1307, USA. ********************************************************************/ #include "gps.h" -#include "garminusb.h" +#include "gpsserial.h" +#include "../gbser.h" #include #include #include @@ -56,50 +58,46 @@ char *rxdata[] = { #if defined (__WIN32__) || defined (__CYGWIN__) #include -/* - * Rather than teaching the rest of this code about Windows serial APIs - * we'll weenie out, violate good layering, and just keep our handle - * internal. This means we ignore that 'fd' number that gets passed in. - */ -static HANDLE comport; +typedef struct { + HANDLE comport; +} win_serial_data; /* * Display an error from the serial subsystem. */ -void GPS_Serial_Error(char *hdr) +void GPS_Serial_Error(const char *mb, ...) { + va_list ap; char msg[200]; char *s; + int b; - strcpy(msg, hdr); - s = msg + strlen(hdr); + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; *s++ = ':'; *s++ = ' '; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, - GetLastError(), 0, s, sizeof(msg) - strlen(hdr) - 2, 0 ); + GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); GPS_Error(msg); } -int32 GPS_Serial_On(const char *port, int32 *fd) +int32 GPS_Serial_On(const char *port, gpsdevh **dh) { DCB tio; COMMTIMEOUTS timeout; - - if (gps_is_usb) { - switch (gusb_open(port)) { - case 0: return 0; - case 1: return 1; - case 2: exit(0); - } - } - - comport = CreateFile(port, GENERIC_READ|GENERIC_WRITE, 0, NULL, + HANDLE comport; + const char *xname = fix_win_serial_name(port); + win_serial_data *wsd = xcalloc(sizeof (win_serial_data), 1); + *dh = (gpsdevh*) wsd; + GPS_Diag("Opening %s\n", xname); + comport = CreateFile(xname, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (comport == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("CreateFile"); + GPS_Serial_Error("CreateFile on '%s' failed", xname); gps_errno = SERIAL_ERROR; return 0; } @@ -125,7 +123,7 @@ int32 GPS_Serial_On(const char *port, int32 *fd) tio.StopBits = ONESTOPBIT; if (!SetCommState (comport, &tio)) { - GPS_Serial_Error("SetCommState"); + GPS_Serial_Error("SetCommState on port '%s' failed", port); CloseHandle(comport); comport = INVALID_HANDLE_VALUE; gps_errno = SERIAL_ERROR; @@ -152,35 +150,31 @@ int32 GPS_Serial_On(const char *port, int32 *fd) gps_errno = SERIAL_ERROR; return 0; } - *fd = 1; + wsd->comport = comport; return 1; } -int32 GPS_Serial_Off(const char *port, int32 fd) +int32 GPS_Serial_Off(gpsdevh *dh) { - if (gps_is_usb) { - gusb_close(port); - } else { - CloseHandle(comport); - comport = INVALID_HANDLE_VALUE; - } + win_serial_data *wsd = (win_serial_data*)dh; + CloseHandle(wsd->comport); + wsd->comport = INVALID_HANDLE_VALUE; + xfree(wsd); return 1; } -int32 GPS_Serial_Chars_Ready(int32 fd) +int32 GPS_Serial_Chars_Ready(gpsdevh *dh) { COMSTAT lpStat; DWORD lpErrors; + win_serial_data *wsd = (win_serial_data*)dh; - ClearCommError(comport, &lpErrors, &lpStat); + ClearCommError(wsd->comport, &lpErrors, &lpStat); return (lpStat.cbInQue > 0); } -int32 GPS_Serial_Wait(int32 fd) +int32 GPS_Serial_Wait(gpsdevh *fd) { - - if (gps_is_usb) return 1; - /* Wait a short time before testing if data is ready. * The GPS II, in particular, has a noticable time responding * with a response to the device inquiry and if we give up on this @@ -192,13 +186,14 @@ int32 GPS_Serial_Wait(int32 fd) return GPS_Serial_Chars_Ready(fd); } -int32 GPS_Serial_Flush(int32 fd) +int32 GPS_Serial_Flush(gpsdevh *fd) { return 1; } -int32 GPS_Serial_Write(int32 ignored, const void *obuf, int size) +int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) { + win_serial_data *wsd = (win_serial_data*)dh; DWORD len; /* @@ -211,26 +206,22 @@ int32 GPS_Serial_Write(int32 ignored, const void *obuf, int size) if (size == 0) { return 0; } - WriteFile (comport, obuf, size, &len, NULL); + WriteFile (wsd->comport, obuf, size, &len, NULL); if (len != (DWORD) size) { fatal ("Write error. Wrote %d of %d bytes.\n", len, size); } return len; } -int32 GPS_Serial_Read(int32 ignored, void *ibuf, int size) +int32 GPS_Serial_Read(gpsdevh * dh, void *ibuf, int size) { DWORD cnt = 0; + win_serial_data *wsd = (win_serial_data*)dh; - ReadFile(comport, ibuf, size, &cnt, NULL); + ReadFile(wsd->comport, ibuf, size, &cnt, NULL); return cnt; } -int32 GPS_Serial_Close(int32 fd, const char *port) -{ - return 1; -} - #else #include @@ -238,85 +229,10 @@ int32 GPS_Serial_Close(int32 fd, const char *port) #include #include -static struct termios gps_ttysave; - -/* @func GPS_Serial_Restoretty *********************************************** -** -** Save tty information for the serial post to be used -** -** @param [r] port [const char *] port e.g. ttyS1 -** -** @return [int32] false upon error -************************************************************************/ - -int32 GPS_Serial_Savetty(const char *port) -{ - int32 fd; - - if (gps_is_usb) return 1; - - if((fd = open(port, O_RDWR))==-1) - { - perror("open"); - gps_errno = SERIAL_ERROR; - GPS_Error("SERIAL: Cannot open serial port"); - return 0; - } - - if(tcgetattr(fd,&gps_ttysave)==-1) - { - perror("tcgetattr"); - gps_errno = HARDWARE_ERROR; - GPS_Error("SERIAL: tcgetattr error"); - return 0; - } - - if(!GPS_Serial_Close(fd,port)) - { - gps_errno = SERIAL_ERROR; - GPS_Error("GPS_Serial_Savetty: Close error"); - return 0; - } - - return 1; -} - - -/* @func GPS_Serial_Restoretty *********************************************** -** -** Restore serial post to condition before AJBGPS called -** -** @param [r] port [const char *] port e.g. ttyS1 -** -** @return [int32] false upon error -************************************************************************/ - -int32 GPS_Serial_Restoretty(const char *port) -{ - int32 fd; - - if (gps_is_usb) return 1; - - if((fd = open(port, O_RDWR))==-1) - { - perror("open"); - gps_errno = HARDWARE_ERROR; - GPS_Error("SERIAL: Cannot open serial port"); - return 0; - } - - if(tcsetattr(fd, TCSAFLUSH, &gps_ttysave)==-1) - { - perror("ioctl"); - gps_errno = HARDWARE_ERROR; - GPS_Error("SERIAL: tcsetattr error"); - return 0; - } - - return 1; -} - - +typedef struct { + int fd; /* File descriptor */ + struct termios gps_ttysave; +} posix_serial_data; /* @func GPS_Serial_Open *********************************************** ** @@ -328,9 +244,10 @@ int32 GPS_Serial_Restoretty(const char *port) ** @return [int32] false upon error ************************************************************************/ -int32 GPS_Serial_Open(int32 *fd, const char *port) +int32 GPS_Serial_Open(gpsdevh *dh, const char *port) { struct termios tty; + posix_serial_data *psd = (posix_serial_data *)dh; /* * This originally had O_NDELAY | O_NOCTTY in here, but this @@ -338,21 +255,20 @@ int32 GPS_Serial_Open(int32 *fd, const char *port) * and the rest of the code doesn't _REALLY_ handle the partial * write/retry case anyway. - robertl */ - if((*fd = open(port, O_RDWR))==-1) + if((psd->fd = open(port, O_RDWR))==-1) { - perror("open"); - GPS_Error("SERIAL: Cannot open serial port"); + GPS_Serial_Error("XSERIAL: Cannot open serial port '%s'", port); gps_errno = SERIAL_ERROR; return 0; } - if(tcgetattr(*fd,&tty)==-1) + if(tcgetattr(psd->fd,&psd->gps_ttysave)==-1) { - perror("tcgetattr"); - GPS_Error("SERIAL: tcgetattr error"); - gps_errno = SERIAL_ERROR; + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcgetattr error"); return 0; } + tty = psd->gps_ttysave; tty.c_cflag &= ~(CSIZE); tty.c_cflag |= (CREAD | CS8 | CLOCAL); @@ -365,18 +281,40 @@ int32 GPS_Serial_Open(int32 *fd, const char *port) tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 0; - if(tcsetattr(*fd,TCSANOW,&tty)==-1) + if(tcsetattr(psd->fd,TCSANOW,&tty)==-1) { - perror("tcsetattr"); - GPS_Error("SERIAL: tcsetattr error"); + GPS_Serial_Error("SERIAL: tcsetattr error"); return 0; } return 1; } -int32 GPS_Serial_Read(int32 handle, void *ibuf, int size) +/* + * Display an error from the serial subsystem. + */ +void GPS_Serial_Error(const char *mb, ...) +{ + va_list ap; + char msg[200]; + char *s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + +// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, +// GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); + strcat(msg, strerror(errno)); + GPS_Error(msg); +} + +int32 GPS_Serial_Read(gpsdevh *dh, void *ibuf, int size) { + posix_serial_data *psd = (posix_serial_data *)dh; #if GARMULATOR static int l; static char *rp; @@ -398,13 +336,14 @@ int32 GPS_Serial_Read(int32 handle, void *ibuf, int size) return 1; #else - return read(handle, ibuf, size); + return read(psd->fd, ibuf, size); #endif } -int32 GPS_Serial_Write(int32 handle, const void *obuf, int size) +int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) { - return write(handle, obuf, size); + posix_serial_data *psd = (posix_serial_data *)dh; + return write(psd->fd, obuf, size); } @@ -416,14 +355,13 @@ int32 GPS_Serial_Write(int32 handle, const void *obuf, int size) ** ** @return [int32] false upon error ************************************************************************/ -int32 GPS_Serial_Flush(int32 fd) +int32 GPS_Serial_Flush(gpsdevh *fd) { - if (gps_is_usb) return 1; - - if(tcflush(fd,TCIOFLUSH)) + posix_serial_data *psd = (posix_serial_data *)fd; + + if(tcflush(psd->fd,TCIOFLUSH)) { - perror("tcflush"); - GPS_Error("SERIAL: tcflush error"); + GPS_Serial_Error("SERIAL: tcflush error"); gps_errno = SERIAL_ERROR; return 0; } @@ -443,14 +381,20 @@ int32 GPS_Serial_Flush(int32 fd) ** @return [int32] false upon error ************************************************************************/ -int32 GPS_Serial_Close(int32 fd, const char *port) +int32 GPS_Serial_Close(gpsdevh *fd) { - if (gps_is_usb) return 1; + posix_serial_data *psd = (posix_serial_data *)fd; + + if(tcsetattr(psd->fd, TCSAFLUSH, &psd->gps_ttysave)==-1) + { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } - if(close(fd)==-1) + if(close(psd->fd)==-1) { - perror("close"); - GPS_Error("SERIAL: Error closing serial port"); + GPS_Serial_Error("SERIAL: Error closing serial port"); gps_errno = SERIAL_ERROR; return 0; } @@ -468,10 +412,13 @@ int32 GPS_Serial_Close(int32 fd, const char *port) ** @return [int32] true if chars waiting ************************************************************************/ -int32 GPS_Serial_Chars_Ready(int32 fd) +int32 GPS_Serial_Chars_Ready(gpsdevh *dh) { fd_set rec; struct timeval t; + posix_serial_data *psd = (posix_serial_data *)dh; + int32 fd = psd->fd; + #if GARMULATOR static foo; /* Return sporadic reads just to torment the rest of the code. */ @@ -506,21 +453,20 @@ int32 GPS_Serial_Chars_Ready(int32 fd) ** @return [int32] true if serial chars waiting ************************************************************************/ -int32 GPS_Serial_Wait(int32 fd) +int32 GPS_Serial_Wait(gpsdevh *dh) { fd_set rec; struct timeval t; - - if (gps_is_usb) return 1; + posix_serial_data *psd = (posix_serial_data *)dh; FD_ZERO(&rec); - FD_SET(fd,&rec); + FD_SET(psd->fd,&rec); t.tv_sec = 0; - t.tv_usec = usecDELAY; + t.tv_usec = 180000; /* Microseconds before GPS sends A001 */ - (void) select(fd+1,&rec,NULL,NULL,&t); - if(FD_ISSET(fd,&rec)) + (void) select(psd->fd+1,&rec,NULL,NULL,&t); + if(FD_ISSET(psd->fd,&rec)) return 1; return 0; @@ -538,21 +484,14 @@ int32 GPS_Serial_Wait(int32 fd) ** @return [int32] success ************************************************************************/ -int32 GPS_Serial_On(const char *port, int32 *fd) +int32 GPS_Serial_On(const char *port, gpsdevh **dh) { - if (gps_is_usb) { - return gusb_init(); - } - if(!GPS_Serial_Savetty(port)) - { - GPS_Error("Cannot access serial port"); - gps_errno = SERIAL_ERROR; - return 0; - } + posix_serial_data *psd = xcalloc(sizeof (posix_serial_data), 1); + *dh = (gpsdevh*) psd; - if(!GPS_Serial_Open(fd,port)) + if(!GPS_Serial_Open((gpsdevh *) psd,port)) { - GPS_Error("Cannot open serial port"); + GPS_Error("Cannot open serial port '%s'", port); gps_errno = SERIAL_ERROR; return 0; } @@ -572,115 +511,18 @@ int32 GPS_Serial_On(const char *port, int32 *fd) ** @return [int32] success ************************************************************************/ -int32 GPS_Serial_Off(const char *port, int32 fd) +int32 GPS_Serial_Off(gpsdevh *dh) { - if(!GPS_Serial_Close(fd,port)) + + if(!GPS_Serial_Close(dh)) { GPS_Error("Error Closing port"); gps_errno = HARDWARE_ERROR; return 0; } + dh = NULL; - if(!GPS_Serial_Restoretty(port)) - { - GPS_Error("Error restoring port"); - gps_errno = HARDWARE_ERROR; - return 0; - } - - return 1; -} - - - - - - - -/* @func GPS_Serial_Open_NMEA ****************************************** -** -** Open a serial port 8bits 1 stop bit 4800 baud -** -** @param [w] fd [int32 *] file descriptor -** @param [r] port [const char *] port e.g. ttyS1 -** -** @return [int32] false upon error -************************************************************************/ - -int32 GPS_Serial_Open_NMEA(int32 *fd, const char *port) -{ - struct termios tty; - - - if((*fd = open(port, O_RDWR | O_NDELAY | O_NOCTTY))==-1) - { - perror("open"); - GPS_Error("SERIAL: Cannot open serial port"); - gps_errno = SERIAL_ERROR; - return 0; - } - - - if(tcgetattr(*fd,&tty)==-1) - { - perror("tcgetattr"); - GPS_Error("SERIAL: tcgetattr error"); - gps_errno = SERIAL_ERROR; - return 0; - } - - - tty.c_cflag |= (CREAD | CS8 | CSIZE | CLOCAL); - cfsetospeed(&tty,B4800); - cfsetispeed(&tty,B4800); - - tty.c_lflag &= 0x0; - tty.c_iflag &= 0x0; - tty.c_oflag &= 0x0; - - - if(tcsetattr(*fd,TCSANOW,&tty)==-1) - { - perror("tcsetattr"); - GPS_Error("SERIAL: tcsetattr error"); - return 0; - } - return 1; } - - - - - - -/* @func GPS_Serial_On_NMEA ******************************************** -** -** Set up port for NMEA -** -** @param [r] port [const char *] port -** @param [w] fd [int32 *] file descriptor -** -** @return [int32] success -************************************************************************/ -int32 GPS_Serial_On_NMEA(const char *port, int32 *fd) -{ - - if(!GPS_Serial_Savetty(port)) - { - GPS_Error("Cannot access serial port"); - gps_errno = SERIAL_ERROR; - return 0; - } - - if(!GPS_Serial_Open_NMEA(fd,port)) - { - GPS_Error("Cannot open serial port"); - gps_errno = SERIAL_ERROR; - return 0; - } - - return 1; -} #endif /* __WIN32__ */ diff --git a/jeeps/gpsserial.h b/jeeps/gpsserial.h index 7d3958d48..bf245105e 100644 --- a/jeeps/gpsserial.h +++ b/jeeps/gpsserial.h @@ -11,20 +11,22 @@ extern "C" #define usecDELAY 180000 /* Microseconds before GPS sends A001 */ -int32 GPS_Serial_Chars_Ready(int32 fd); -int32 GPS_Serial_Close(int32 fd, const char *port); -int32 GPS_Serial_Open(int32 *fd, const char *port); -int32 GPS_Serial_Open_NMEA(int32 *fd, const char *port); -int32 GPS_Serial_Restoretty(const char *port); -int32 GPS_Serial_Savetty(const char *port); -int32 GPS_Serial_On(const char *port, int32 *fd); -int32 GPS_Serial_Off(const char *port, int32 fd); -int32 GPS_Serial_Wait(int32 fd); -int32 GPS_Serial_Flush(int32 fd); -int32 GPS_Serial_On_NMEA(const char *port, int32 *fd); -int32 GPS_Serial_Read(int32 ignored, void *ibuf, int size); -int32 GPS_Serial_Write(int32 ignored, const void *obuf, int size); -void GPS_Serial_Error(char *hdr); +int32 GPS_Serial_Chars_Ready(gpsdevh * fd); +// int32 GPS_Serial_Close(int32 fd, const char *port); +// int32 GPS_Serial_Open(int32 *fd, const char *port); +// int32 GPS_Serial_Open_NMEA(int32 *fd, const char *port); +// int32 GPS_Serial_Restoretty(const char *port); +// int32 GPS_Serial_Savetty(const char *port); +int32 GPS_Serial_On(const char *port, gpsdevh **fd); +int32 GPS_Serial_Off(gpsdevh *fd); +int32 GPS_Serial_Wait(gpsdevh *fd); +int32 GPS_Serial_Flush(gpsdevh *fd); +// int32 GPS_Serial_On_NMEA(const char *port, gpsdevh **fd); +int32 GPS_Serial_Read(gpsdevh *fd, void *ibuf, int size); +int32 GPS_Serial_Write(gpsdevh *fd, const void *obuf, int size); +int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); +int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); +void GPS_Serial_Error(const char *hdr, ...); #endif diff --git a/jeeps/gpsusbcommon.c b/jeeps/gpsusbcommon.c new file mode 100644 index 000000000..35ac8d684 --- /dev/null +++ b/jeeps/gpsusbcommon.c @@ -0,0 +1,268 @@ +/* + Garmin USB layer - OS independent component. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "gps.h" +#include "garminusb.h" +#include "gpsusbcommon.h" + +/* + * This receive logic is a little convoluted as we go to some efforts here + * to hide most of the differences between the bulk only and bulk-interrupt + * protocols as exhibited in the handhelds and dashtops. + */ + +enum { + rs_fromintr, + rs_frombulk +} receive_state; + +static gusb_llops_t *gusb_llops; + +/* Decide when to truncate packets for debug output */ +#define DEBUG_THRESH ((global_opts.debug_level < 5) && (i > 10)) + +/* Called from OS layer to register its low-level entry points. */ +void +gusb_register_ll(gusb_llops_t *p) +{ + gusb_llops = p; +} + +int +gusb_close(gpsdevh *dh) +{ + garmin_usb_packet scratch; + + memset(&scratch, 0, sizeof(scratch)); + + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(&scratch, sizeof(scratch)); + break; + default: + break; + } + + gusb_llops->llop_close(dh); + return 1; + +#if BOOGER + garmin_usb_packet scratch = {0}; +abort(); + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(dh, &scratch, sizeof(scratch)); + break; + } + + return 1; +#endif +} + + +int +gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) +{ + int rv; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int orig_receive_state; +top: + orig_receive_state = receive_state; + switch (receive_state) { + case rs_fromintr: + rv = gusb_llops->llop_get_intr(ibuf, sz); + break; + case rs_frombulk: + rv = gusb_llops->llop_get_bulk(ibuf, sz); + break; + default: + fatal("Unknown receiver state %d\n", receive_state); + } + + if (gps_show_bytes) { + int i; + const char *m1, *m2; + unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]); + + GPS_Diag("RX (%s) [%d]:", + receive_state == rs_fromintr ? "intr" : "bulk", rv); + + for(i=0;igusb_pkt.pkt_id[0], pkttype, &m2); +if ((rv == 0) && (receive_state == rs_frombulk) ) {m1= "RET2INTR";m2=NULL;}; + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + } + + /* Adjust internal state and retry the read */ + if ((rv > 0) && (ibuf->gusb_pkt.pkt_id[0] == GUSB_REQUEST_BULK)) { + receive_state = rs_frombulk; + goto top; + } + /* + * If we were reading from the bulk pipe and we just got + * a zero request, adjust our internal state. + * It's tempting to retry the read here to hide this "stray" + * packet from our callers, but that only works when you know + * there's another packet coming. That works in every case + * except the A000 discovery sequence. + */ + if ((receive_state == rs_frombulk) && (rv <= 0)) { + receive_state = rs_fromintr; + } + + return rv; +} + +int +gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) +{ + unsigned int rv, i; + + unsigned char *obuf = (unsigned char *) &opkt->dbuf; + const char *m1, *m2; + + rv = gusb_llops->llop_send(opkt, sz); + + if (gps_show_bytes) { + const unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]); + GPS_Diag("TX [%d]:", sz); + + for(i=0;igusb_pkt.pkt_id[0], pkttype, &m2); + + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + } + /* + * Recursion, when used in a disciplined way, can be our friend. + * + * The Garmin protocol requires that packets that are exactly + * a multiple of the max tx size be followed by a zero length + * packet. Do that here so we can see it in debugging traces. + */ + + if (sz && !(sz % gusb_llops->max_tx_size)) { + gusb_cmd_send(opkt, 0); + } + + return (rv); +} + +void +gusb_list_units() +{ + int i; + + for (i = 0; i < GUSB_MAX_UNITS; i++) { + if (garmin_unit_info[i].serial_number) { + printf("%d %lu %lu %s\n", i, + garmin_unit_info[i].serial_number, + garmin_unit_info[i].unit_id, + garmin_unit_info[i].product_identifier + ); + } + } +} + +void +gusb_id_unit(struct garmin_unit_info *gu) +{ + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + gusb_cmd_send((garmin_usb_packet *)oid, sizeof(oid)); + + for (i = 0; i < 25; i++) { + iresp.gusb_pkt.type = 0; + if (gusb_cmd_get(&iresp, sizeof(iresp)) < 0) { + return; + } + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { + gu->product_identifier = xstrdup((char *) iresp.gusb_pkt.databuf+4); + gu->unit_id = le_read16(iresp.gusb_pkt.databuf+0); + gu->unit_version = le_read16(iresp.gusb_pkt.databuf+2); + } + /* + * My goodnesss, this is fragile. During command syncup, + * we need to know if we're at the end. The 0xfd packet + * is promised by Garmin engineering to be the last. + */ + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return; + } + fatal("Unable to sync with Garmin USB device in %d attempts.", i); +} + +void +gusb_syncup(void) +{ + static int unit_number; + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + /* + * This is our first communication with the unit. + */ + receive_state = rs_fromintr; + + for(i = 0; i < 25; i++) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); + garmin_unit_info[unit_number].serial_number = serial_number; + gusb_id_unit(&garmin_unit_info[unit_number]); + + unit_number++; + + return; + } + } + fatal("Unable to establish USB syncup\n"); +} diff --git a/jeeps/gpsusbcommon.h b/jeeps/gpsusbcommon.h new file mode 100644 index 000000000..b0865f5f0 --- /dev/null +++ b/jeeps/gpsusbcommon.h @@ -0,0 +1,45 @@ +/* + Garmin USB layer - OS independent component. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + * The 'low level ops' are registered by the OS layer (win32, libusb, etc.) + * to provide gruntwork features for the common USB layer. + */ +typedef int (*gusb_llop_get)(garmin_usb_packet *ibuf, size_t sz); +typedef int (*gusb_llop_send)(const garmin_usb_packet *opkt, size_t sz); +typedef int (*gusb_llop_close) (gpsdevh *dh); + +typedef struct gusb_llops { + gusb_llop_get llop_get_intr; + gusb_llop_get llop_get_bulk; + gusb_llop_send llop_send; + gusb_llop_close llop_close; + int max_tx_size; +} gusb_llops_t; + +/* Provided by the common code. */ +void gusb_syncup(void); +void gusb_register_ll(struct gusb_llops *); +void gusb_list_units(void); + +/* Provided by the OS layers */ +// int gusb_init(const char *portname, gpsdev **dh); + diff --git a/jeeps/gpsusbint.h b/jeeps/gpsusbint.h index 3a0e00137..8d91da24a 100644 --- a/jeeps/gpsusbint.h +++ b/jeeps/gpsusbint.h @@ -3,7 +3,7 @@ These symbols should not be publicly used. They're "friend" functions of USB details internal to jeeps. - Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ */ -int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet); +int32 GPS_Packet_Read_usb(gpsdevh *fd, GPS_PPacket *packet, int eatbulk); void GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n); -int32 GPS_Write_Packet_usb(int32 fd, GPS_PPacket packet); +int32 GPS_Write_Packet_usb(gpsdevh *fd, GPS_PPacket packet); diff --git a/jeeps/gpsusbread.c b/jeeps/gpsusbread.c index cff319a23..e266011dd 100644 --- a/jeeps/gpsusbread.c +++ b/jeeps/gpsusbread.c @@ -1,7 +1,7 @@ /* Decompose an incoming USB packet to make it look like a serial one. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2006, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,29 +23,45 @@ #include "garminusb.h" #include "gpsusbint.h" -int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet) +/* + * Return values are: + * Negative on error. + * 1 if read success - even if empty packet. + */ +int32 GPS_Packet_Read_usb(gpsdevh *dh, GPS_PPacket *packet, int eat_bulk) { int32 n; - int32 i; int32 payload_size; - const char *m1; - const char *m2; garmin_usb_packet pkt; + memset(&pkt, 0, sizeof(pkt)); +do_over: n = gusb_cmd_get(&pkt, sizeof(pkt)); - if (1 && gps_show_bytes) { - GPS_Diag("\nRx Data:[%d]",n); - for (i = 0; i < n; i++) - GPS_Diag("%02x ", pkt.dbuf[i]); - for (i = 0; i < n; i++) - GPS_Diag("%c", isalnum(pkt.dbuf[i]) ? pkt.dbuf[i] : '.'); - m1 = Get_Pkt_Type(pkt.gusb_pkt.pkt_id[0], pkt.gusb_pkt.databuf[0], &m2); - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - + if ( n < 0 ) { + /* + * We (probably) used to have a GPS and it went away + * while we were speaking with it. Perhaps batteries + * died or it was unplugged or something. + */ + gps_errno = PROTOCOL_ERROR; + return n; } + /* + * This is a horrible hack for 276/296. This family sometimes + * switches between bulk and interrupt on EVERY packet. Rather + * than bother all the callers with that bit of unpleasantness, + * silently consume zero byte "switch back to intr" packets here. + * + * The one caller that doesn't want this hidden is device discovery + * in the A000 handler. + */ + if ((n == 0) && eat_bulk) { + goto do_over; + } + /* * Populate members of serial packet from USB packet. The * copy here seems wasteful, but teaching all the callers about @@ -57,5 +73,6 @@ int32 GPS_Packet_Read_usb(int32 fd, GPS_PPacket *packet) payload_size = le_read32(&pkt.gusb_pkt.datasz); (*packet)->n = (UC) payload_size; memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size); - return payload_size; + + return 1; } diff --git a/jeeps/gpsusbsend.c b/jeeps/gpsusbsend.c index 8e0877a45..bd376b7e0 100644 --- a/jeeps/gpsusbsend.c +++ b/jeeps/gpsusbsend.c @@ -1,7 +1,7 @@ /* Form GarminUSB packets to send. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,9 +43,10 @@ GPS_Make_Packet_usb(GPS_PPacket *packet, UC type, UC *data, int16 n) } int32 -GPS_Write_Packet_usb(int32 fd, GPS_PPacket packet) +GPS_Write_Packet_usb(gpsdevh *dh, GPS_PPacket packet) { - garmin_usb_packet gp = {0}; + garmin_usb_packet gp; + memset(&gp, 0, sizeof(gp)); /* diff --git a/jeeps/gpsusbstub.c b/jeeps/gpsusbstub.c index 04659c3ee..b42d7091a 100644 --- a/jeeps/gpsusbstub.c +++ b/jeeps/gpsusbstub.c @@ -1,7 +1,7 @@ /* Stubs to keep build happy when USB just isn't available to us. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,38 +19,18 @@ */ -#if NO_USB -#include "garminusb.h" +#include "config.h" +#include "../defs.h" +#if !HAVE_LIBUSB const char no_usb[] = "USB suport is not available in this build.\n"; -int -gusb_cmd_send(const garmin_usb_packet *obuf, size_t sz) -{ - fatal(no_usb); -} - -int -gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) -{ - fatal(no_usb); -} int -gusb_open(const char *portname) +gusb_init(const char *portname) { fatal(no_usb); -} - -int -gusb_init() -{ - fatal(no_usb); -} - -int -gusb_close(const char *portname) -{ return 0; } -#endif /* defined(NO_USB) */ + +#endif /* defined(HAVE_LIBUSB) */ diff --git a/jeeps/gpsusbwin.c b/jeeps/gpsusbwin.c index 7362caf9c..1fe48959f 100644 --- a/jeeps/gpsusbwin.c +++ b/jeeps/gpsusbwin.c @@ -1,8 +1,7 @@ -#if !defined(NO_USB) /* Windows layer of Garmin/USB protocol. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004, 2006, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +30,7 @@ #include "gps.h" #include "gpsapp.h" #include "garminusb.h" +#include "gpsusbcommon.h" /* Constants from Garmin doc. */ @@ -48,142 +48,30 @@ DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b, 0x #define IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE CTL_CODE \ (FILE_DEVICE_UNKNOWN, 0x851, METHOD_BUFFERED, FILE_ANY_ACCESS) +typedef struct { + int booger; +} winusb_unit_data; -static HANDLE *usb_handle ; +static HANDLE *usb_handle = INVALID_HANDLE_VALUE; static int usb_tx_packet_size ; -static const char oinit[12] = {0, 0, 0, 0, 0x05, 0, 0, 0, 0, 0, 0, 0}; -garmin_usb_packet iresp; -garmin_usb_packet iresp_junk; -static int ct; - -static char * id_unit(void); - -int -gusb_open(const char *pname) -{ - int maxtries; - int maxct = 10; - int unit_number = 0; - int req_unit_number = 0; - - SP_INTERFACE_DEVICE_DATA devinterface; - PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; - SP_DEVINFO_DATA devinfo; - HDEVINFO hdevinfo; - DWORD size; - if (ct++) return 1; - - if (strlen(pname) > 4) { - req_unit_number = atoi(pname+4); - GPS_Diag("Searching for USB unit number %d\n", unit_number); -// if (req_unit_number == -2) { -// printf("%d %u %s\n", 0, 3019840053, "GPSMap60CS Software Version 3.50"); -// exit(0); -// } - } - - hdevinfo = SetupDiGetClassDevs( (GUID *) &GARMIN_GUID, NULL, NULL, - DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); - - if (hdevinfo == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("SetupDiGetClassDevs failed"); - return 0; - } - - /* Get the device associated with this index. */ - devinterface.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); - if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, (GUID *) &GARMIN_GUID, - 0, &devinterface)) { - GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); - warning("Is the unit powered up and connected?"); - return 0; - } - - SetupDiGetDeviceInterfaceDetail(hdevinfo, &devinterface, - NULL, 0, &size, NULL); - - pdd = malloc(size); - pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - devinfo.cbSize = sizeof(SP_DEVINFO_DATA); - - if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, &devinterface, pdd, size, NULL, &devinfo)) { - GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); - return 0; - } - - /* Whew. All that just to get something we can open... */ - GPS_Diag("Windows GUID for interface %d is \n\t%s\n", unit_number, - pdd->DevicePath); - usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL ); - if (usb_handle == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("CreateFile failed"); - return 0; - } - - if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, NULL, 0, - &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, &size, NULL)) { - fatal("Couldn't get USB packet size.\n"); - } - - if (pdd) { - free(pdd); - } - SetupDiDestroyDeviceInfoList(hdevinfo); - - for (maxtries = maxct; maxtries; maxtries--) { - - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_get(&iresp, sizeof(iresp)); - - if ((le_read16(iresp.gusb_pkt.pkt_id) == 6) && - (le_read32(iresp.gusb_pkt.datasz) == 4)) { - unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); - GPS_Diag("Serial %u. Synced in %d\n", - serial_number, - maxct - maxtries); - garmin_unit_info[unit_number].serial_number = serial_number; - garmin_unit_info[unit_number].os_identifier = strdup(pdd->DevicePath); - garmin_unit_info[unit_number].product_identifier = id_unit(); - if (req_unit_number < 0) { - printf("%d %u %s\n", unit_number, serial_number, garmin_unit_info[unit_number].product_identifier); - return 2; - } - return 1; - } - } - fatal("Unable to establish USB syncup within %d tries.\n", maxct); - return 0; -} - -int -gusb_close(const char *portname) +static int +gusb_win_close(gpsdevh *handle) { if (usb_handle != INVALID_HANDLE_VALUE) { -#if 0 - /* FIXME: we should probably release things and delete the "ct" - * reference count above... - */ CloseHandle(usb_handle); usb_handle = INVALID_HANDLE_VALUE; -#endif } - return 0; + + return 0; } -int -gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) +static int +gusb_win_get(garmin_usb_packet *ibuf, size_t sz) { DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; unsigned char *buf = (unsigned char *) &ibuf->dbuf; - int i; int tsz=0; - unsigned char *obuf = buf; while (sz) { /* The driver wrongly (IMO) rejects reads smaller than @@ -201,99 +89,165 @@ gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) break; } } - - if (gps_show_bytes) { - const char *m1, *m2; - printf("RX [%d]:", tsz); - for(i=0;igusb_pkt.pkt_id[0], ibuf->gusb_pkt.databuf[0], &m2); - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - printf("\n"); - } return tsz; } -int -gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) +static int +gusb_win_get_bulk(garmin_usb_packet *ibuf, size_t sz) +{ + int n; + DWORD rsz; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + + n = ReadFile(usb_handle, buf, sz, &rsz, NULL); + + return rsz; +} + +static int +gusb_win_send(const garmin_usb_packet *opkt, size_t sz) { DWORD rsz; - size_t i; unsigned char *obuf = (unsigned char *) &opkt->dbuf; - const char *m1, *m2; /* The spec warns us about making writes an exact multiple * of the packet size, but isn't clear whether we can issue * data in a single call to WriteFile if it spans buffers. */ WriteFile(usb_handle, obuf, sz, &rsz, NULL); - if (gps_show_bytes) { - printf("TX [%d]:", rsz); - for(i=0;igusb_pkt.pkt_id[0], opkt->gusb_pkt.databuf[0], &m2); - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - } if (rsz != sz) { - fatal ("Error sending %d bytes. Successfully sent %d\n", sz, rsz); - } - - if (0 == sz % usb_tx_packet_size) { - DWORD sz2; - GPS_Diag("Writing padding buffer.\n"); - WriteFile(usb_handle, 0, 0, &sz2, NULL); + fatal ("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); } return rsz; } -static char * -id_unit(void) +static gusb_llops_t win_llops = { + gusb_win_get, + gusb_win_get_bulk, + gusb_win_send, + gusb_win_close +}; + +static +HANDLE * garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA *infodata) { -static const unsigned char oid[12] = {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; - /* - * Identify the unit before getting into all the protocol gunk. - * We get two packets back, but we discard the protocol array - * for now. - */ + DWORD size; + PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; + SP_DEVINFO_DATA devinfo; + + SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + NULL, 0, &size, NULL); - gusb_cmd_send((garmin_usb_packet *)oid, sizeof(oid)); - gusb_cmd_get(&iresp, sizeof(iresp)); - gusb_cmd_get(&iresp_junk, sizeof(iresp_junk)); + pdd = xmalloc(size); + pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - if (iresp.gusb_pkt.type == 20 && - le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { - return strdup(iresp.gusb_pkt.databuf+4); + devinfo.cbSize = sizeof(SP_DEVINFO_DATA); + if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + pdd, size, NULL, &devinfo)) { + GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); + return NULL; } - return NULL; -} + /* Whew. All that just to get something we can open... */ + GPS_Diag("Windows GUID for interface is \n\t%s\n", + pdd->DevicePath); + if (usb_handle != INVALID_HANDLE_VALUE) { + fatal("garmin_usb_start called while device already started.\n"); + } -#if 0 -main() + usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL ); + if (usb_handle == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); + return NULL; + } + + if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, + NULL, 0, &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, + &size, NULL)) { + fatal("Couldn't get USB packet size.\n"); + } + win_llops.max_tx_size = usb_tx_packet_size; + + gusb_syncup(); + + return usb_handle; +} + +/* + * Main entry point from the upper layer. Walk the device tree, find our + * device, and light it up. + */ +int +gusb_init(const char *pname, gpsdevh **dh) { - DWORD sz; -char ocmd[] = {00, 00, 00, 00, 05, 00, 00, 00, 00, 00, 00, 00}; -char ocmd2[] = {0x14, 00, 00, 00, 0xfe, 00, 00, 00, 00, 00, 00, 00}; - gusb_open(); - WriteFile(usb_handle, ocmd, sizeof(ocmd), &sz, NULL); - printf("Wrote %d\n", sz); - usb_intr_get(); - - WriteFile(usb_handle, ocmd2, sizeof(ocmd2), &sz, NULL); - printf("Wrote %d\n", sz); - usb_intr_get(); - - WriteFile(usb_handle, ocmd2, sizeof(ocmd2), &sz, NULL); - printf("Wrote %d\n", sz); - usb_intr_get(); + int req_unit_number = 0; + int un = 0; + int match; + + HDEVINFO hdevinfo; + SP_DEVICE_INTERFACE_DATA devinterface; + + winusb_unit_data *wud = xcalloc(sizeof (winusb_unit_data), 1); + *dh = (gpsdevh*) wud; + + gusb_register_ll(&win_llops); + + if (strlen(pname) > 4) { + if (0 == strcmp(pname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(pname+4); + } + } + + hdevinfo = SetupDiGetClassDevs( (GUID *) &GARMIN_GUID, NULL, NULL, + DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + + if (hdevinfo == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("SetupDiGetClassDevs failed"); + warning("Is the Garmin USB driver installed?"); + return 0; + } + + devinterface.cbSize = sizeof(devinterface); + + if (req_unit_number >= 0) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID *) &GARMIN_GUID, + req_unit_number, &devinterface)) { + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?\nIs it really a USB unit? If it's serial, don't choose USB, choose serial.", un); + return 0; + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + return 1; + } + + /* + * Out unit nunber is less than zero, so loop over all units + * and display them. + */ + for(match = 0;;match++) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID *) &GARMIN_GUID, match, &devinterface)) { + if (GetLastError() == ERROR_NO_MORE_ITEMS) { + break; + } else { + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?", un); + return 0; + } + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + gusb_close(NULL); + } + gusb_list_units(); + exit (0); } -#endif -#endif /* !defined(NO_USB) */ + diff --git a/jeeps/gpsutil.c b/jeeps/gpsutil.c index 7311d019a..4078e2e5e 100644 --- a/jeeps/gpsutil.c +++ b/jeeps/gpsutil.c @@ -499,14 +499,20 @@ void GPS_Fatal(char *s) ** @@ ****************************************************************************/ -void GPS_Error(char *s) +void GPS_Error(char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + if(!gps_error) return; - fprintf(stderr,"[ERROR] %s\n",s); - fflush(stderr); + fprintf(stderr, "[ERROR] "); + vfprintf(stderr, fmt, argp); + fprintf(stderr, "\n"); + + va_end(argp); return; } @@ -585,15 +591,17 @@ void GPS_Disable_Warning(void) ** @@ ****************************************************************************/ -void GPS_User(char *s) +void GPS_User(const char *fmt, ...) { - if(!gps_user) - return; + va_list argp; + va_start (argp, fmt); - fprintf(stdout,"%s\n",s); - fflush(stdout); + if (gps_user) { + vfprintf(stdout, fmt, argp); + fflush(stdout); + } - return; + va_end(argp); } /* @func GPS_Disable_User *********************************************** diff --git a/jeeps/gpsutil.h b/jeeps/gpsutil.h index 30027885c..faf1e0f06 100644 --- a/jeeps/gpsutil.h +++ b/jeeps/gpsutil.h @@ -25,13 +25,14 @@ void GPS_Util_Put_Uint(UC *s, const uint32 v); uint32 GPS_Util_Get_Uint(const UC *s); void GPS_Warning(char *s); -void GPS_Error(char *s); +void GPS_Error(char *fmt, ...); +void GPS_Serial_Error(const char *hdr, ...); void GPS_Fatal(char *s); void GPS_Enable_Error(void); void GPS_Enable_Warning(void); void GPS_Disable_Error(void); void GPS_Disable_Warning(void); -void GPS_User(char *s); +void GPS_User(const char *fmt, ...); void GPS_Disable_User(void); void GPS_Enable_User(void); void GPS_Diagnose(int32 c); diff --git a/kml.c b/kml.c index 5d2b6baec..aad687678 100644 --- a/kml.c +++ b/kml.c @@ -1,7 +1,7 @@ /* Support for Google Earth & Keyhole "kml" format. - Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2005, 2006 Robert Lipe, robertlipe@usa.net Updates by Andrew Kirmse, akirmse at google.com This program is free software; you can redistribute it and/or modify @@ -28,14 +28,28 @@ static char *opt_export_lines = NULL; static char *opt_export_points = NULL; static char *opt_line_width = NULL; static char *opt_line_color = NULL; +static char *opt_floating = NULL; +static char *opt_extrude = NULL; +static char *opt_trackdata = NULL; +static char *opt_units = NULL; +static char *opt_labels = NULL; +static char *opt_max_position_points = NULL; static int export_lines; static int export_points; +static int floating; +static int extrude; +static int trackdata; +static int max_position_points; + +static int indent_level; static waypoint *wpt_tmp; +static int wpt_tmp_queued; +static const char *posnfilename; +static char *posnfilenametmp; -FILE *fd; -FILE *ofd; +static FILE *ofd; typedef struct { double latitude; @@ -45,79 +59,110 @@ typedef struct { static int point3d_list_len; static point3d *point3d_list; +static int realtime_positioning; +static int do_indentation = 1; + +#define TD(FMT,DATA) kml_write_xml(0, "

" FMT "
" FMT "
]]>\n"); + kml_write_xml(-1, "\n"); + + /* We won't always have times. Garmin saved tracks, for example... */ + if (td->start && td->end) { + char time_string[64]; + kml_write_xml(1, "\n"); + xml_fill_in_time(time_string, td->start, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + xml_fill_in_time(time_string, td->end, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + kml_write_xml(-1, "\n"); + } +} + + +static +void kml_output_header(const route_head *header, computed_trkdata*td) { - fprintf(ofd, "\n"); - fprintf(ofd, " 1\n"); - write_optional_xml_entity(ofd, " ", "name", header->rte_name); - write_optional_xml_entity(ofd, " ", "desc", header->rte_desc); + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + } + kml_write_xmle("name", header->rte_name); + kml_output_trkdescription(header, td); - if (export_points && header->rte_waypt_ct > 0) { - // Put the points in a subfolder - fprintf(ofd, " \n"); - fprintf(ofd, " 1\n"); - fprintf(ofd, " Points\n"); - } + if (export_points && header->rte_waypt_ct > 0) { + // Put the points in a subfolder + kml_write_xml(1, "\n"); + kml_write_xml(0, "Points\n"); + } // Create an array for holding waypoint coordinates so that we // can produce a LineString at the end. @@ -211,28 +501,82 @@ static void kml_output_header(const route_head *header) point3d_list_len = 0; } +/* Rather than a default "top down" view, view from the side to highlight + * topo features. + */ +static void kml_output_lookat(const waypoint *waypointp) +{ + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "66\n"); + kml_write_xml(-1, "\n"); +} + +/* Output something interesing when we can for route and trackpoints */ +static void kml_output_description(const waypoint *pt) +{ + char *alt_units; + double alt; + + if (!trackdata) { + return; + } + + alt = fmt_distance(pt->altitude, &alt_units); + + kml_write_xml(1,"\n"); + + TD("Longitude: %f", pt->longitude); + TD("Latitude: %f", pt->latitude); + if (pt->altitude != unknown_alt) TD2("Altitude: %.1f %s", alt, alt_units); + if (pt->heartrate) TD("Heart rate: %d", pt->heartrate); + if (pt->cadence) TD("Cadence: %d", pt->cadence); + if (pt->temperature) TD("Temperature: %.1f", pt->temperature); + if (pt->speed > 0) { + char *spd_units; + double spd = fmt_speed(pt->speed, &spd_units); + TD2("Speed: %.1f %s", spd, spd_units); + } + TD("Heading: %.1f", pt->course); + kml_write_xml(-1, "

\n"); + kml_write_xml(-1, "]]>\n"); +} static void kml_output_point(const waypoint *waypointp, const char *style) { // Save off this point for later use point3d *pt = &point3d_list[point3d_list_len]; point3d_list_len++; + pt->longitude = waypointp->longitude; pt->latitude = waypointp->latitude; pt->altitude = waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude; if (export_points) { - fprintf(ofd, "\t\n"); - fprintf(ofd, "\t %s\n", style); - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t %f,%f,%f\n", + kml_write_xml(1, "\n"); + if (atoi(opt_labels)) { + kml_write_xmle("name", waypointp->shortname); + } + kml_write_xml(0, "\n"); + kml_output_description(waypointp); + kml_output_lookat(waypointp); + kml_output_timestamp(waypointp); + kml_write_xml(0, "%s\n", style); + kml_write_xml(1, "\n"); + if (floating) { + kml_write_xml(0, "absolute\n"); + } + if (extrude) { + kml_write_xml(0, "1\n"); + } + kml_write_xml(0, "%f,%f,%f\n", pt->longitude, pt->latitude, pt->altitude); - fprintf(ofd, "\t \n"); + kml_write_xml(-1, "\n"); - // Timestamp - kml_output_timestamp(waypointp); - fprintf(ofd, "\t\n"); + kml_write_xml(-1, "\n"); } } @@ -242,33 +586,72 @@ static void kml_output_tailer(const route_head *header) int i; if (export_points && point3d_list_len > 0) { - fprintf(ofd, " \n"); + kml_write_xml(-1,"\n"); } // Add a linestring for this track? if (export_lines && point3d_list_len > 0) { - fprintf(ofd, "\t\n"); - fprintf(ofd, "\t #lineStyle\n"); - fprintf(ofd, "\t Path\n"); - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t \n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "Path\n"); +// fprintf(ofd, "\t \n"); + kml_write_xml(0, "#lineStyle\n"); + kml_write_xml(1, "\n"); + if (floating) { + kml_write_xml(0, "absolute\n"); + } + if (extrude) { + kml_write_xml(0, "1\n"); + } + kml_write_xml(0, "1\n"); + kml_write_xml(1, "\n"); for (i = 0; i < point3d_list_len; ++i) - fprintf(ofd, "%f,%f,%f ", + kml_write_xml(0, "%f,%f,%f\n", point3d_list[i].longitude, point3d_list[i].latitude, point3d_list[i].altitude); - fprintf(ofd, "\n\t \n"); - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t\n"); + kml_write_xml(-1,"\n"); + kml_write_xml(-1, "\n"); +// fprintf(ofd, "\t \n"); + kml_write_xml(-1, "\n"); } xfree(point3d_list); point3d_list = NULL; - fprintf(ofd, "\n"); + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } +} + +static +char * +kml_lookup_gc_icon(const waypoint *waypointp) +{ + const char *icon; + char *rb; + + /* This could be done so much better in C99 with designated + * initializers... + */ + switch (waypointp->gc_data.type) { + case gt_traditional: icon = "2.png"; break; + case gt_multi: icon = "3.png"; break; + case gt_virtual: icon = "4.png"; break; + case gt_letterbox: icon = "5.png"; break; + case gt_event: icon = "6.png"; break; + case gt_ape: icon = "7.png"; break; + case gt_locationless: icon = "8.png"; break; // No unique icon. + case gt_suprise: icon = "8.png"; break; + case gt_webcam: icon = "11.png"; break; + case gt_cito: icon = "13.png"; break; + case gt_earth: icon = "earthcache.png"; break; + case gt_mega: icon = "6.png"; break; // No unique icon yet. + default: icon = "8.png"; break; + } + + xasprintf(&rb, "http://www.geocaching.com/images/kml/%s", icon); + return rb; } /* @@ -277,31 +660,95 @@ static void kml_output_tailer(const route_head *header) static void kml_waypt_pr(const waypoint *waypointp) { - fprintf(ofd, "\t\n"); - write_optional_xml_entity(ofd, "\t", "name", waypointp->shortname); - fprintf(ofd, "\t #waypoint\n"); + const char *icon; + + kml_write_xml(1, "\n"); + + kml_write_xmle("name", waypointp->shortname); // Description - if (waypointp->url) { + if (waypointp->url && waypointp->url[0]) { char * odesc = xml_entitize(waypointp->url); - fprintf(ofd, "\t "); - fputs("\n", ofd); - fputs(odesc, ofd); + kml_write_xml(0,"\n"); + kml_write_xml(0,"\n"); + if (waypointp->url_link_text && waypointp->url_link_text[0]) { + char *olink = xml_entitize(waypointp->url_link_text); + kml_write_xml(0,"%s]]>", odesc, olink); + xfree(olink); + } + else + fputs(odesc, ofd); + + if (!global_opts.no_smart_icons && + waypointp->gc_data.diff && waypointp->gc_data.terr) { + if (waypointp->gc_data.placer) { + char *p = xml_entitize(waypointp->gc_data.placer); + fprintf(ofd, " by %s]]>", p); + xfree(p); + } + fprintf(ofd, " %s (%3.1f/%3.1f)", + gs_get_container(waypointp->gc_data.container), + waypointp->gc_data.diff / 10.0, + waypointp->gc_data.terr / 10.0); + if (waypointp->gc_data.desc_short.utfstring) { + // Dont entitize it - either XML or HTML. + // Wrap it in a cdata and let Earth work it out. + + fprintf(ofd, "%s

]]>\n", waypointp->gc_data.desc_short.utfstring); + + } + } + kml_write_xml(0, "
\n"); xfree(odesc); - fprintf(ofd, "\n\t
\n"); + } + + // Timestamp + kml_output_timestamp(waypointp); + + // Icon - but only if it looks like a URL. + icon = opt_deficon ? opt_deficon : waypointp->icon_descr; + if (icon && strstr(icon, "://")) { + kml_write_xml(1, "\n"); + + } else if (!global_opts.no_smart_icons && waypointp->gc_data.diff && waypointp->gc_data.terr) { + char *is = kml_lookup_gc_icon(waypointp); + kml_write_xml(1, "\n"); + xfree(is); + } else { + kml_write_xml(0, "#waypoint\n"); } // Location - fprintf(ofd, "\t \n"); - fprintf(ofd, "\t\t%f,%f,%f\n", + kml_write_xml(1, "\n"); + + if (extrude) { + kml_write_xml(0, "1\n"); + } + + if (floating) { + kml_write_xml(0, "absolute\n"); + } + + kml_write_xml(0, "%f,%f,%f\n", waypointp->longitude, waypointp->latitude, waypointp->altitude == unknown_alt ? 0.0 : waypointp->altitude); - fprintf(ofd, "\t \n"); + kml_write_xml(-1, "\n"); + - // Timestamp - kml_output_timestamp(waypointp); - fprintf(ofd, "\t
\n"); + kml_write_xml(-1, "
\n"); } /* @@ -310,17 +757,20 @@ static void kml_waypt_pr(const waypoint *waypointp) static void kml_track_hdr(const route_head *header) { - kml_output_header(header); + computed_trkdata *td; + track_recompute(header, &td); + kml_output_header(header, td); + xfree(td); } static void kml_track_disp(const waypoint *waypointp) { - kml_output_point(waypointp, "#track"); + kml_output_point(waypointp, "#track"); } static void kml_track_tlr(const route_head *header) { - kml_output_tailer(header); + kml_output_tailer(header); } /* @@ -329,7 +779,7 @@ static void kml_track_tlr(const route_head *header) static void kml_route_hdr(const route_head *header) { - kml_output_header(header); + kml_output_header(header, NULL); } static void kml_route_disp(const waypoint *waypointp) @@ -344,52 +794,146 @@ static void kml_route_tlr(const route_head *header) void kml_write(void) { - // Parse options - export_lines = (0 == strcmp("1", opt_export_lines)); - export_points = (0 == strcmp("1", opt_export_points)); - - fprintf(ofd, "\n"); - fprintf(ofd, "\n"); - // TODO(akirmse): Put in device name, maybe time? - fprintf(ofd, "GPS device\n"); - fprintf(ofd, "1\n"); + char import_time[100]; + time_t now; + + // Parse options + export_lines = (0 == strcmp("1", opt_export_lines)); + export_points = (0 == strcmp("1", opt_export_points)); + floating = (!! strcmp("0", opt_floating)); + extrude = (!! strcmp("0", opt_extrude)); + trackdata = (!! strcmp("0", opt_trackdata)); + + kml_write_xml(0,"\n"); + kml_write_xml(1,"\n"); + kml_write_xml(1,"\n"); + + now = current_time(); + strftime(import_time, sizeof(import_time), "%c", localtime(&now)); + if (realtime_positioning) + kml_write_xml(0, "GPS position\n"); + else + kml_write_xml(0, "GPS device\n"); + + if (now) { + kml_write_xml(0, "Created %s\n", import_time); + } // Style settings for bitmaps - kml_write_bitmap_style("track", 4, 128, 0, 32, 32); - kml_write_bitmap_style("waypoint", 4, 160, 0, 32, 32); - kml_write_bitmap_style("route", 4, 160, 0, 32, 32); + kml_write_bitmap_style("route", "http://maps.google.com/mapfiles/kml/pal4/icon61.png"); + kml_write_bitmap_style("track", "http://maps.google.com/mapfiles/kml/pal4/icon60.png"); + kml_write_bitmap_style("waypoint", "http://maps.google.com/mapfiles/kml/pal4/icon61.png"); // Style settings for line strings - fprintf(ofd, "\n"); - - fprintf(ofd, "\n"); - fprintf(ofd, "Waypoints\n"); - fprintf(ofd, "1\n"); + kml_write_xml(1, "\n"); + + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Waypoints\n"); + } waypt_disp_all(kml_waypt_pr); - fprintf(ofd, "\n"); + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } // Output trackpoints - fprintf(ofd, "\n"); - fprintf(ofd, "Tracks\n"); - fprintf(ofd, "1\n"); + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Tracks\n"); + } track_disp_all(kml_track_hdr, kml_track_tlr, kml_track_disp); - fprintf(ofd, "\n"); - + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + // Output routes - fprintf(ofd, "\n"); - fprintf(ofd, "Routes\n"); - fprintf(ofd, "1\n"); - route_disp_all(kml_route_hdr, kml_route_tlr, kml_route_disp); - fprintf(ofd, "\n"); + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Routes\n"); + route_disp_all(kml_route_hdr, kml_route_tlr, kml_route_disp); + kml_write_xml(-1, "\n"); + } - fprintf(ofd, "\n"); + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); +} + +/* + * This depends on the table being sorted correctly. + */ +static +char * +kml_get_posn_icon(int freshness) +{ + int i; + for (i = 0; i < sizeof(kml_tracking_icons) / sizeof(kml_tracking_icons[0]); i++) { + if (freshness >= kml_tracking_icons[i].freshness) + return kml_tracking_icons[i].icon; + } + return "http://maps.google.com/mapfiles/kml/pal3/icon59.png"; +} + + +static route_head *posn_trk_head = NULL; + +static void +kml_wr_position(waypoint *wpt) +{ + static time_t last_valid_fix; + + if (!posn_trk_head) { + posn_trk_head = route_head_alloc(); + track_add_head(posn_trk_head); + } + + if (last_valid_fix == 0) last_valid_fix = current_time(); + + /* We want our waypoint to have a name, but not our trackpoint */ + if (!wpt->shortname) { + if (wpt->fix == fix_none) { + wpt->shortname = xstrdup("ESTIMATED Position"); + } else { + wpt->shortname = xstrdup("Position"); + } + } + + switch (wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree (wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + case fix_unknown: + break; + default: + last_valid_fix = wpt->creation_time; + } + + wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); + + track_add_wpt(posn_trk_head, waypt_dupe(wpt)); + + waypt_add(wpt); + kml_write(); + waypt_del(wpt); + + /* + * If we are keeping only a recent subset of the trail, trim the + * head here. + */ + while (max_position_points && + (posn_trk_head->rte_waypt_ct >= max_position_points)) { + waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list); + track_del_wpt(posn_trk_head, tonuke); + } } ff_vecs_t kml_vecs = { @@ -402,5 +946,7 @@ ff_vecs_t kml_vecs = { kml_read, kml_write, NULL, - kml_args + kml_args, + CET_CHARSET_UTF8, 1, /* CET-REVIEW */ + { NULL, NULL, NULL, kml_wr_position_init, kml_wr_position, kml_wr_deinit } }; diff --git a/lowranceusr.c b/lowranceusr.c index fd6d4288d..06c553aca 100644 --- a/lowranceusr.c +++ b/lowranceusr.c @@ -2,7 +2,7 @@ Access to Lowrance USR files. Contributed to gpsbabel by Jason Rust (jrust at rustyparts.com) - Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -131,12 +131,36 @@ const lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = { { 10019, "Shower" }, /* person */ { DEF_ICON, "Tunnel" }, + /* This list comes from 'wifinder' from ifinder H20 Color */ + + { 10062, "Interesting Land Feature" }, + { 10063, "Global Location" }, + { 10064, "Note" }, + { 10065, "Ghost" }, + { 10066, "Letter" }, + { 10067, "Multi-Treasure" }, + { 10068, "Mystery Or Puzzle" }, + { 10069, "Treasure" }, + { 10070, "Webmail" }, + { 10071, "Sun" }, + { 10072, "Musical Note" }, + { 10073, "Camera/Movie Theater" }, + { 10074, "Star" }, + { 10075, "Coffee Mug" }, + { 10076, "Books" }, + { 10077, "Historical Marker" }, + { 10078, "Tools/Repair" }, + { 10079, "Favorite" }, + { 10080, "Arena" }, + { 10081, "Golf Course" }, + { 10082, "Money/Atm" }, + { -1, NULL } }; static FILE *file_in; static FILE *file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; static unsigned short waypt_out_count; static unsigned int trail_count, lowrance_route_count; @@ -156,9 +180,10 @@ static char *seg_break; #define DEGREESTORADIANS 0.017453292 #define SECSTO2000 946713600 #define MAX_TRAIL_POINTS 9999 +#define UNKNOWN_USR_ALTITUDE METERS_TO_FEET(-10000) /* -10000ft is how the unit stores unknown */ /* Jan 1, 2000 00:00:00 */ -struct tm base_time = { 0, 0, 0, 1, 0, 100, 5, 1, -1 }; +const time_t base_time_secs = 946706400; static size_t @@ -194,11 +219,22 @@ long int lowranceusr_find_icon_number_from_desc(const char *desc) { const lowranceusr_icon_mapping_t *i; + int n; if (!desc) { return DEF_ICON; } + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + for (i = lowranceusr_icon_value_table; i->icon; i++) { if (case_ignore_strcmp(desc,i->icon) == 0) { return i->value; @@ -215,7 +251,8 @@ lowranceusr_fread(void *buff, size_t size, size_t members, FILE * fp) br = fread(buff, size, members, fp); if (br != members) { - fatal(MYNAME ": requested to read %d bytes, read %d bytes.\n", members, br); + fatal(MYNAME ": requested to read %lu bytes, read %lu bytes.\n", + (unsigned long) members, (unsigned long) br); } return (br); @@ -224,12 +261,12 @@ lowranceusr_fread(void *buff, size_t size, size_t members, FILE * fp) static arglist_t lowranceusr_args[] = { {"ignoreicons", &ignoreicons, "Ignore event marker icons", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"merge", &merge, "(USR output) Merge into one segmented track", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"break", &seg_break, "(USR input) Break segments into separate tracks", - NULL, ARGTYPE_BOOL }, - {NULL, NULL, NULL, NULL, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static void @@ -256,7 +293,7 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } /** @@ -290,7 +327,6 @@ lowranceusr_parse_waypt(waypoint *wpt_tmp) long int TextLen; time_t waypt_time; short waypt_type; - time_t base_time_secs = mktime(&base_time); lowranceusr_fread(&buff[0], 4, 1, file_in); wpt_tmp->latitude = lat_mm_to_deg(le_read32(&buff[0])); @@ -298,9 +334,13 @@ lowranceusr_parse_waypt(waypoint *wpt_tmp) wpt_tmp->longitude = lon_mm_to_deg(le_read32(&buff[0])); lowranceusr_fread(&buff[0], 4, 1, file_in); wpt_tmp->altitude = FEET_TO_METERS(le_read32(&buff[0])); + if (wpt_tmp->altitude <= UNKNOWN_USR_ALTITUDE) { + wpt_tmp->altitude = unknown_alt; + } lowranceusr_fread(&buff[0], 4, 1, file_in); TextLen = buff[0]; - lowranceusr_fread(&buff[0], TextLen, 1, file_in); + if (TextLen) + lowranceusr_fread(&buff[0], TextLen, 1, file_in); buff[TextLen] = '\0'; wpt_tmp->shortname = xstrdup(buff); @@ -332,6 +372,12 @@ lowranceusr_parse_waypt(waypoint *wpt_tmp) /* Symbol ID */ lowranceusr_fread(&buff[0], 4, 1, file_in); wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(le_read32(&buff[0])); + if (!wpt_tmp->icon_descr[0]) { + char nbuf[10]; + snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff)); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(nbuf); + } /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */ lowranceusr_fread(&buff[0], 2, 1, file_in); @@ -525,7 +571,7 @@ if (global_opts.debug_level >= 1) track_add_head(trk_tmp); trk_head = trk_tmp; } - route_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); if (global_opts.debug_level >= 1) printf("LOWRANCE parse_trails: Trail pt lat %f lon %f\n", wpt_tmp->latitude, wpt_tmp->longitude); @@ -592,7 +638,10 @@ lowranceusr_waypt_disp(const waypoint *wpt) char *name; char *comment; int alt = METERS_TO_FEET(wpt->altitude); - time_t base_time_secs = mktime(&base_time); + + if (alt == unknown_alt) { + alt = UNKNOWN_USR_ALTITUDE; + } Lat = lat_deg_to_mm(wpt->latitude); my_fwrite4(&Lat, file_out); @@ -946,5 +995,6 @@ ff_vecs_t lowranceusr_vecs = { data_read, data_write, NULL, - lowranceusr_args + lowranceusr_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/macgpsbabel/English.lproj/MainMenu.nib/info.nib b/macgpsbabel/English.lproj/MainMenu.nib/info.nib index 0f6ae32f9..a2c81127d 100644 --- a/macgpsbabel/English.lproj/MainMenu.nib/info.nib +++ b/macgpsbabel/English.lproj/MainMenu.nib/info.nib @@ -3,23 +3,22 @@ IBDocumentLocation - 69 10 356 240 0 0 1152 746 + 116 209 356 240 0 0 1440 878 IBEditorPositions 29 - 69 252 302 44 0 0 1152 746 + 93 299 319 44 0 0 1440 878 IBFramework Version - 364.0 + 443.0 IBOpenObjects - 305 + 29 229 21 - 678 - 29 + 305 IBSystem Version - 7M34 + 8H14 diff --git a/macgpsbabel/English.lproj/MainMenu.nib/objects.nib b/macgpsbabel/English.lproj/MainMenu.nib/objects.nib index fb2a7b0dae32c2003f59772c8ce3bfacac539740..318ae06f4fbf6e06467de97d3940a455b623bc49 100644 GIT binary patch literal 27700 zcmeHwd7MHd&8DQ8KLB*&?+#n#%!oWZz4h*7mWs5UN+#dFHpP6at>27*qAaI}7 z*wf~EpBl%p)p3o9Q6w6pxZ)P!VWLUgo<@xt%`@iOu6bUUTyErke^uw4uG7mf$oss% zo{4k%)cMt~etT8@YO!Kea#PF-CX#W>-z9wimgbG=bb9QHmgdDP+b*yI$tC`zU$D2+ z=@BbhR0-?tQy@*LL^9f?3TO1EjYg_EZbi%TRMOuTwpx<$P^5#)n)dJhG@m(UMa!aC zEF22>lc8uN)0;{2kYMj+QFqvimNP?E_l$IU)QXlftVApt30iU1-`6|9(xV&kPrLn( zBEW8FQ9SP7#M0^Ez$}0E4@@T#fuz;im|PmN!ofq+>8ceiP0>g)9u3d9zHeZlhh4y*BMzFzuYx*`+^G%^mf#FC4r$qI+Rn@*2LQvsr%-X}=P>DMAi zAr$KQ>H4o1^{~bYmaZV8dlhR-(fASl1IMH* XmIBytZY%2c!dM{hXQY^qiEXe%q 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 + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + MacGPSBabel + CFBundleIconFile + mgb.icns + CFBundleIdentifier + com.gpsbabel.MacGPSBabel + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + mGPS + CFBundleVersion + 1.2.8-beta20060219 + NSAppleScriptEnabled + YES + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/macgpsbabel/MacGPSBabel.applescript b/macgpsbabel/MacGPSBabel.applescript index 76d6c1204..a60412337 100644 --- a/macgpsbabel/MacGPSBabel.applescript +++ b/macgpsbabel/MacGPSBabel.applescript @@ -100,7 +100,8 @@ on will open theObject end will open -on will close theObject +-- to work around the NSReceiverEvaluationScriptError we need to use should close instead of will close +on should close theObject log "will close - " & name of theObject if theObject is window "SelectGPS" then -- store user defaults for this window @@ -112,7 +113,16 @@ on will close theObject -- unhide MacGPSBabel window set visible of window "MacGPSBabel" to true end if -end will close + + if theObject is window "filterWindow" then + set the title of button "filterButton" of window "MacGPSBabel" to "Setup Filters" + end if + + -- workarund NSReceiverEvaluationScriptError bug + set visible of theObject to false + return false + +end should close -- handler for the File>Open menu item @@ -728,6 +738,7 @@ on showFilters() set the title of button "filterButton" of window "MacGPSBabel" to "Setup Filters" end if end showFilters + -- create the filter code on applyFilters() set filterText to "" diff --git a/macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj b/macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj new file mode 100644 index 000000000..017ed87ed --- /dev/null +++ b/macgpsbabel/MacGPSBabel.xcodeproj/project.pbxproj @@ -0,0 +1,400 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAppleScriptBuildPhase section */ + 6AC682D709C45A8F0081607C /* AppleScript */ = { + isa = PBXAppleScriptBuildPhase; + buildActionMask = 2147483647; + contextName = ""; + files = ( + 6AC682D809C45A8F0081607C /* MacGPSBabel.applescript in AppleScript */, + ); + isSharedContext = 0; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXAppleScriptBuildPhase section */ + +/* Begin PBXBuildFile section */ + 6AC682D809C45A8F0081607C /* MacGPSBabel.applescript in AppleScript */ = {isa = PBXBuildFile; fileRef = DA206CF3015C4E8B03C91932 /* MacGPSBabel.applescript */; settings = {ATTRIBUTES = (Debug, ); }; }; + 6AC682DA09C45A8F0081607C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 6AC682DB09C45A8F0081607C /* mgb.icns in Resources */ = {isa = PBXBuildFile; fileRef = F52E6CB4059959B801A80064 /* mgb.icns */; }; + 6AC682DC09C45A8F0081607C /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 6AC682C009C459350081607C /* MainMenu.nib */; }; + 6AC682DD09C45A8F0081607C /* gpsbabel in Resources */ = {isa = PBXBuildFile; fileRef = 6AC682C509C4596E0081607C /* gpsbabel */; }; + 6AC682DE09C45A8F0081607C /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 6AC682CB09C45A660081607C /* Credits.rtf */; }; + 6AC682E009C45A8F0081607C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 6AC682E209C45A8F0081607C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + 6AC682E309C45A8F0081607C /* AppleScriptKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA206CF1015C4E2903C91932 /* AppleScriptKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildStyle section */ + 4A9504CCFFE6A4B311CA0CBA /* Development */ = { + isa = PBXBuildStyle; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OPTIMIZATION_CFLAGS = "-O0"; + ZERO_LINK = YES; + }; + name = Development; + }; + 4A9504CDFFE6A4B311CA0CBA /* Deployment */ = { + isa = PBXBuildStyle; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + OTHER_OSAFLAGS = "-x"; + ZERO_LINK = NO; + }; + name = Deployment; + }; +/* End PBXBuildStyle section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 6AC682C109C459350081607C /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; + 6AC682C509C4596E0081607C /* gpsbabel */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = gpsbabel; path = ../gpsbabel; sourceTree = SOURCE_ROOT; }; + 6AC682CB09C45A660081607C /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; }; + 6AC682E909C45A8F0081607C /* MacGPSBabel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacGPSBabel.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6AC682EB09C45ACD0081607C /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + DA206CF1015C4E2903C91932 /* AppleScriptKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleScriptKit.framework; path = /System/Library/Frameworks/AppleScriptKit.framework; sourceTree = ""; }; + DA206CF3015C4E8B03C91932 /* MacGPSBabel.applescript */ = {isa = PBXFileReference; explicitFileType = sourcecode.applescript; fileEncoding = 30; path = MacGPSBabel.applescript; sourceTree = ""; }; + DA206CF4015C4E8B03C91932 /* AppleScriptKit.sdef */ = {isa = PBXFileReference; lastKnownFileType = text.sdef; name = AppleScriptKit.sdef; path = /System/Library/Frameworks/AppleScriptKit.framework/Versions/A/Resources/AppleScriptKit.sdef; sourceTree = ""; }; + F52E6CB4059959B801A80064 /* mgb.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = mgb.icns; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6AC682E109C45A8F0081607C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AC682E209C45A8F0081607C /* Cocoa.framework in Frameworks */, + 6AC682E309C45A8F0081607C /* AppleScriptKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Scripts */ = { + isa = PBXGroup; + children = ( + DA206CF3015C4E8B03C91932 /* MacGPSBabel.applescript */, + ); + name = Scripts; + sourceTree = ""; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + DA206CF1015C4E2903C91932 /* AppleScriptKit.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 6AC682E909C45A8F0081607C /* MacGPSBabel.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* Application */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Scripts */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = Application; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 6AC682EB09C45ACD0081607C /* Info.plist */, + 6AC682CB09C45A660081607C /* Credits.rtf */, + 6AC682C009C459350081607C /* MainMenu.nib */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + DA206CF4015C4E8B03C91932 /* AppleScriptKit.sdef */, + F52E6CB4059959B801A80064 /* mgb.icns */, + 6AC682C509C4596E0081607C /* gpsbabel */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 6AC682D609C45A8F0081607C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 6AC682D509C45A8F0081607C /* MacGPSBabel */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6AC682E409C45A8F0081607C /* Build configuration list for PBXNativeTarget "MacGPSBabel" */; + buildPhases = ( + 6AC682D609C45A8F0081607C /* Headers */, + 6AC682D709C45A8F0081607C /* AppleScript */, + 6AC682D909C45A8F0081607C /* Resources */, + 6AC682DF09C45A8F0081607C /* Sources */, + 6AC682E109C45A8F0081607C /* Frameworks */, + ); + buildRules = ( + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ""; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = /Users/jeremya/Dev/MacGPSBabel; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + name = MacGPSBabel; + productInstallPath = "$(HOME)/Applications"; + productName = Application; + productReference = 6AC682E909C45A8F0081607C /* MacGPSBabel.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 6AC6829D09C44F090081607C /* Build configuration list for PBXProject "MacGPSBabel" */; + buildSettings = { + }; + buildStyles = ( + 4A9504CCFFE6A4B311CA0CBA /* Development */, + 4A9504CDFFE6A4B311CA0CBA /* Deployment */, + ); + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* Application */; + projectDirPath = ""; + targets = ( + 6AC682D509C45A8F0081607C /* MacGPSBabel */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6AC682D909C45A8F0081607C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AC682DA09C45A8F0081607C /* InfoPlist.strings in Resources */, + 6AC682DB09C45A8F0081607C /* mgb.icns in Resources */, + 6AC682DC09C45A8F0081607C /* MainMenu.nib in Resources */, + 6AC682DD09C45A8F0081607C /* gpsbabel in Resources */, + 6AC682DE09C45A8F0081607C /* Credits.rtf in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6AC682DF09C45A8F0081607C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AC682E009C45A8F0081607C /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 6AC682C009C459350081607C /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 6AC682C109C459350081607C /* English */, + ); + name = MainMenu.nib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 6AC6829E09C44F090081607C /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Development; + }; + 6AC6829F09C44F090081607C /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Deployment; + }; + 6AC682A009C44F090081607C /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Default; + }; + 6AC682E509C45A8F0081607C /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Development; + }; + 6AC682E609C45A8F0081607C /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_OSAFLAGS = "-x"; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 6AC682E709C45A8F0081607C /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)"; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = MacGPSBabel; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = app; + }; + name = Default; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6AC6829D09C44F090081607C /* Build configuration list for PBXProject "MacGPSBabel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6AC6829E09C44F090081607C /* Development */, + 6AC6829F09C44F090081607C /* Deployment */, + 6AC682A009C44F090081607C /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 6AC682E409C45A8F0081607C /* Build configuration list for PBXNativeTarget "MacGPSBabel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6AC682E509C45A8F0081607C /* Development */, + 6AC682E609C45A8F0081607C /* Deployment */, + 6AC682E709C45A8F0081607C /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/mag_pdb.c b/mag_pdb.c new file mode 100644 index 000000000..441ba6924 --- /dev/null +++ b/mag_pdb.c @@ -0,0 +1,243 @@ +/* + + Support of Palm/OS files from Map&Guide based products like + "PowerRoute" 5+6, "Motorrad Routenplaner" + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include +#include + +#include "defs.h" +#if PDBFMTS_ENABLED +#include "coldsync/palm.h" +#include "coldsync/pdb.h" +#include "jeeps/gpsmath.h" + +#define MYNAME "mag_pdb" + +#define PROUTE_MAGIC 0x766d6170 /* vmap */ +#define PROUTE_ROUTE 0x49444154 /* IDAT */ + +static FILE *fd_in; +static struct pdb *pdb_in; +static char *fname_in; + +static arglist_t magpdb_args[] = +{ + ARG_TERMINATOR +}; + +static double +magpdb_to_degree(const int degx) +{ + int m, d, x; + double s, res; + + d = degx / 100000; + x = degx % 100000; + m = x / 1000; + x = x % 1000; + s = (double)(x) / 10; + + GPS_Math_DegMinSec_To_Deg(d, m, s, &res); + + return res; +} + +static void +magpdb_read_data(const char *data, const size_t data_len) +{ + route_head *route; + char *cin = (char *)data; + char *cend = cin + data_len; + + route = route_head_alloc(); + route_add_head(route); + + while (cin < cend) + { + char *lend; + int len; + + lend = strchr(cin, '\x0A'); + if (lend == NULL) break; + + len = (lend - cin); + if (len > 0) + { + double distance; + int hour, min; + *lend = '\0'; + + if (case_ignore_strncmp(cin, "Wegname=", 8) == 0) /* This only works with the german release */ + { /* test-data created with other releases are welcome */ + cin += 8; + if (*cin != '\0') + route->rte_name = xstrdup(cin); + } + else if (case_ignore_strncmp(cin, "Fahrzeit=", 9) == 0) + { + } + else if (case_ignore_strncmp(cin, "Kosten=", 7) == 0) + { + } + else if (case_ignore_strncmp(cin, "Entfernung=", 11) == 0) + { + } + /* check, if line starts with time and distance */ + else if (3 == sscanf(cin, "%d:%d %lf", &hour, &min, &distance)) + { + char *buff, *comma; + + /* detect time-format settings, 12,0 or 12.0 */ + + comma = strchr(cin, '.'); + buff = strchr(cin, ','); + if (comma == NULL) + comma = buff; + else + if ((buff != NULL) && (buff < comma)) + comma = buff; + if (comma != NULL) + { + char separator = *comma; + + /* now we are looking for a sequence like 0,1 NE (123456,654321) */ + + buff = xmalloc(strlen(cin) + 1); /* safe target space for sscanf( ... */ + + comma = cin; + while ((comma = strchr(comma, separator))) + { + int i, xlat, xlon; + waypoint *wpt; + char *cx; + + comma++; + + if (isdigit(*comma) == 0) continue; + if (isdigit(*(comma - 2)) == 0) continue; + + if (4 != sscanf(comma, "%d %s (%d,%d)", &i, buff, &xlon, &xlat)) continue; + if (strchr("NESW", *buff) == NULL) continue; /* north, east, ... */ + + cx = comma - 2; /* go left over delta distance */ + while (isdigit(*cx) != 0) *cx-- = '\0'; + cin = lrtrim(cin); + + for (i = 0; i < 2; i++) /* skip time and distance at start of line */ + { + cin = strchr(cin, ' '); + cin = lrtrim(cin); + } + + wpt = waypt_new(); + + wpt->latitude = magpdb_to_degree(xlat); + wpt->longitude = magpdb_to_degree(xlon); + wpt->description = xstrdup(cin); + + cx = strchr(comma, ')'); /* find tailing notes after the coordinates */ + if (cx != NULL) + { + char *tail = lrtrim(++cx); + if (*tail != '\0') + { + wpt->notes = xstrdup(tail); + } + } + /* generate some waypoints from our route-only format */ + if ((*cin != '-') && (case_ignore_strncmp(cin, "bei ", 4) != 0)) + waypt_add(waypt_dupe(wpt)); + + route_add_wpt(route, wpt); + break; + } + xfree(buff); + } + } + + } + cin = lend + 1; + } +} + +/* ============================================================================================ + * &&& gobal callbacks &&& + * ----------------------------------------------------------------------------------------- */ + +static void magpdb_rd_init(const char *fname) +{ + fname_in = xstrdup(fname); + fd_in = xfopen(fname, "rb", MYNAME); +} + +static void magpdb_rd_deinit(void) +{ + fclose(fd_in); + xfree(fname_in); +} + +static void magpdb_read(void) +{ + struct pdb_record *pdb_rec = NULL; + + + pdb_in = pdb_Read(fileno(fd_in)); + is_fatal((pdb_in == NULL), MYNAME ": read failed."); + + is_fatal((pdb_in->creator != PROUTE_MAGIC), /* identify the database */ + MYNAME ": Not a Map&Guide pdb file (0x%08x).", pdb_in->creator); + + is_fatal((pdb_in->version != 0), /* only version "0" currently seen and tested */ + MYNAME ": This file is from an unsupported version (%d) of Map&Guide and is unsupported.", pdb_in->version + 5); + + is_fatal((pdb_in->type != PROUTE_ROUTE), + MYNAME ": Unknown pdb data type (0x%08x).", pdb_in->type); + + for (pdb_rec = pdb_in->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) + { + char *data = (char *)pdb_rec->data; + + if (be_read16(data) == 0) + { + int len = be_read16(data + 2); + magpdb_read_data(data + 4, len); + } + } + free_pdb(pdb_in); +} + +/* ======================================================================================= */ + +ff_vecs_t magpdb_vecs = { + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_read }, /* real route + emulated waypoints */ + magpdb_rd_init, + NULL, + magpdb_rd_deinit, + NULL, + magpdb_read, + NULL, + NULL, + magpdb_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ +}; +#endif diff --git a/maggeo.c b/maggeo.c index 719ea0aab..e738685a8 100644 --- a/maggeo.c +++ b/maggeo.c @@ -1,7 +1,7 @@ /* Magellan ".gs" files as they appear on USB of Explorist 400,500,600. - Copyright (C) 2005, robertlipe@usa.net + Copyright (C) 2005, 2006 robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,9 +26,12 @@ #define MYNAME "maggeo" +/* Turn this on (remove) after 5.2 becomes widespread. */ +#define FIRMWARE_DOES_88591 0 + static FILE *maggeofile_in; static FILE *maggeofile_out; -static void *desc_handle = NULL; +static short_handle desc_handle = NULL; static void maggeo_writemsg(const char * const buf) @@ -52,6 +55,9 @@ maggeo_rd_deinit(void) static void maggeo_wr_init(const char *fname) { + if (waypt_count() > 200) { + fatal(MYNAME ": eXplorist does not support more than 200 waypoints in one .gs file.\nDecrease the number of waypoints sent.\n"); + } maggeofile_out = xfopen(fname, "wb", MYNAME); desc_handle = mkshort_new_handle(); setshort_length(desc_handle, 20); @@ -62,13 +68,14 @@ static void maggeo_wr_deinit(void) { maggeo_writemsg("PMGNCMD,END"); + mkshort_del_handle(&desc_handle); fclose(maggeofile_out); } static void maggeo_read(void) { - fatal("Reading maggeo is not implemented yet.\n"); + fatal(MYNAME ": Reading maggeo is not implemented yet.\n"); } /* @@ -111,8 +118,13 @@ append(char *buf, const char *str) return; } - cleansed1 = str_utf8_to_ascii(str); + cleansed1 = xstrdup(str); +#if FIRMWARE_DOES_88591 +/* Actually, this function needs needs refactored... */ + cleansed2 = xstrdup(cleansed1); +#else cleansed2 = m330_cleanse(cleansed1); +#endif strcat(buf, cleansed2); @@ -151,7 +163,15 @@ maggeo_waypt_pr(const waypoint *waypointp) lon = (lon_deg * 100.0 + lon); lat = (lat_deg * 100.0 + lat); - ctype = gs_get_cachetype(waypointp->gc_data.type); + /* + * For some reason, Magellan used exactly the GPX spellings of + * everything except this one... + */ + if (waypointp->gc_data.type == gt_suprise) { + ctype = "Mystery Cache"; + } else { + ctype = gs_get_cachetype(waypointp->gc_data.type); + } placeddate = maggeo_fmtdate(waypointp->creation_time); lfounddate = maggeo_fmtdate(waypointp->gc_data.last_found); cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->shortname); @@ -197,9 +217,9 @@ maggeo_waypt_pr(const waypoint *waypointp) if (lfounddate) xfree(lfounddate); if (placeddate) xfree(placeddate); + if (cname) xfree(cname); maggeo_writemsg(obuf); - } static void @@ -208,31 +228,20 @@ maggeo_write(void) waypt_disp_all(maggeo_waypt_pr); } -static -char * -strconsume(char *instr, int *eaten) -{ - const char *origstr = instr; - char *s = instr; - char *e = instr; - - while (e && *e && *e != ',') - *e++; - - *eaten = e - s; - - return (xstrndup(instr, e-s)); - -} - - ff_vecs_t maggeo_vecs = { ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_none }, + { ff_cap_write, ff_cap_none, ff_cap_none }, maggeo_rd_init, maggeo_wr_init, maggeo_rd_deinit, maggeo_wr_deinit, maggeo_read, maggeo_write, + NULL, + NULL, +#if FIRMWARE_DOES_88591 + CET_CHARSET_LATIN1, 0 /* CET-REVIEW */ +#else + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +#endif }; diff --git a/magnav.c b/magnav.c index ebd432a47..dc9af4961 100644 --- a/magnav.c +++ b/magnav.c @@ -20,6 +20,7 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" @@ -52,10 +53,10 @@ struct record { static FILE *file_in; static FILE *file_out; static const char *out_fname; -static void *mkshort_handle; +static short_handle mkshort_handle; -struct pdb *opdb; -struct pdb_record *opdb_rec; +static struct pdb *opdb; +static struct pdb_record *opdb_rec; static void rd_init(const char *fname) @@ -82,7 +83,7 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } static void @@ -270,5 +271,8 @@ ff_vecs_t magnav_vec = { wr_deinit, data_read, data_write, - NULL + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/magproto.c b/magproto.c index ec96fca44..e48a9d560 100644 --- a/magproto.c +++ b/magproto.c @@ -1,7 +1,7 @@ /* Communicate Thales/Magellan serial protocol. - Copyright (C) 2002, 2003, 2004, 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002, 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,21 +24,23 @@ #include "defs.h" #include "magellan.h" +#include "gbser.h" -int bitrate = 4800; -int wptcmtcnt; -int wptcmtcnt_max; +static int bitrate = 4800; +static int wptcmtcnt; +static int wptcmtcnt_max; +static int explorist; #define MYNAME "MAGPROTO" #define MAXCMTCT 200 #define debug_serial (global_opts.debug_level > 1) -static char * termread(char *ibuf, int size); +static char *termread(char *ibuf, int size); static void termwrite(char *obuf, int size); static void mag_readmsg(gpsdata_type objective); static void mag_handon(void); static void mag_handoff(void); -static void *mkshort_handle = NULL; +static short_handle mkshort_handle = NULL; static char *deficon = NULL; static char *bs = NULL; static char *cmts = NULL; @@ -47,6 +49,18 @@ static char *nukewpt = NULL; static int route_out_count; static int waypoint_read_count; static int wpt_len = 8; +static const char *curfname; +static int extension_hint; + +/* + * Magellan's firmware is *horribly* slow to send the next packet after + * we turn around an ack while we are reading from the device. It's + * quite spiffy when we're writing to the device. Since we're *way* + * less likely to lose data while reading from it than it is to lose data + * when we write to it, we turn off the acks when we are predominatly + * reading. + */ +static int suppress_ack; typedef enum { mrs_handoff = 0, @@ -68,14 +82,13 @@ typedef struct mag_rte_elem { */ typedef struct mag_rte_head { queue Q; /* Queue head for child rte_elems */ + char *rte_name; int nelems; } mag_rte_head; static queue rte_wpt_tmp; /* temporary PGMNWPL msgs for routes */ -static FILE *magfile_in; -static FILE *magfile_out; -static int magfd; +static FILE *magfile_h; static mag_rxstate magrxstate; static int mag_error; static unsigned int last_rx_csum; @@ -185,6 +198,8 @@ pid_to_model_t pid_to_model[] = { mm_sportrak, 44, "Sportrak Topo" }, { mm_sportrak, 45, "Mystic" }, { mm_meridian, 46, "MobileMapper" }, + { mm_meridian, 110, "Explorist 100" }, + { mm_meridian, 111, "Explorist 200" }, { mm_unknown, 0, NULL } }; @@ -263,7 +278,7 @@ static void mag_writemsg(const char * const buf) { unsigned int osum = mag_checksum(buf); - int retry_cnt = 20; + int retry_cnt = 5; int i; char obuf[1000]; @@ -445,16 +460,24 @@ retry: waypt_status_disp(waypoint_read_count, waypoint_read_count); } - switch (objective) - { - case wptdata: + + if (extension_hint) { + if (extension_hint == WPTDATAMASK) { waypt_add(wpt); - break; - case rtedata: - ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); - break; - default: - break; + } else if (extension_hint == RTEDATAMASK) { + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + } + } else { + switch (objective) { + case wptdata: + waypt_add(wpt); + break; + case rtedata: + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + break; + default: + break; + } } } if (strncmp(ibuf, "$PMGNTRK,", 7) == 0) { @@ -463,11 +486,30 @@ retry: * Allow lazy allocation of track head. */ if (trk_head == NULL) { + /* These tracks don't have names, so derive one + * from input filename. + */ + const char *s = strrchr(curfname, GB_PATHSEP); + char *e; trk_head = route_head_alloc(); + + if (s) { + s++; /* Skip path delim */ + } else { + s = curfname;/* use name intact */ + } + + /* Whack trailing extension if present. */ + trk_head->rte_name = xstrdup(s); + e = strrchr(trk_head->rte_name, '.'); + if (e) { + *e = '\0'; + } + track_add_head(trk_head); } - route_add_wpt(trk_head, wpt); + track_add_wpt(trk_head, wpt); } if (strncmp(ibuf, "$PMGNRTE,", 7) == 0) { mag_rteparse(ibuf); @@ -483,272 +525,158 @@ retry: ignore_unable = 0; return; } - if (IS_TKN("$PMGNCMD,END") || (is_file && (feof(magfile_in)))) { + if (IS_TKN("$PMGNCMD,END") || (is_file && (feof(magfile_h)))) { found_done = 1; return; } - if (magrxstate != mrs_handoff) - mag_writeack(isum); -} -/* - * termio on Cygwin is apparently broken, so we revert to Windows serial. - */ -#if defined (__WIN32__) || defined (__CYGWIN__) - -#include - -DWORD -mkspeed(bitrate) -{ - switch (bitrate) { - case 1200: return CBR_1200; - case 2400: return CBR_2400; - case 4800: return CBR_4800; - case 9600: return CBR_9600; - case 19200: return CBR_19200; - case 57600: return CBR_57600; - case 115200: return CBR_115200; - default: return CBR_4800; + if (magrxstate != mrs_handoff) { + mag_writeack(isum); } } -HANDLE comport = NULL; - -#define xCloseHandle(a) if (a) { CloseHandle(a); } a = NULL; +static void *serial_handle = NULL; -static -int -terminit(const char *portname, int create_ok) +static int +terminit(const char *portname, int create_ok) { - DCB tio; - COMMTIMEOUTS timeout; - - is_file = 0; - - xCloseHandle(comport); - - comport = CreateFile(portname, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, NULL); - - if (comport == INVALID_HANDLE_VALUE) { - goto try_as_file; - } - tio.DCBlength = sizeof(DCB); - GetCommState (comport, &tio); - tio.BaudRate = mkspeed(bitrate); - tio.fBinary = TRUE; - tio.fParity = TRUE; - tio.fOutxCtsFlow = FALSE; - tio.fOutxDsrFlow = FALSE; - tio.fDtrControl = DTR_CONTROL_ENABLE; - tio.fDsrSensitivity = FALSE; - tio.fTXContinueOnXoff = TRUE; - tio.fOutX = FALSE; - tio.fInX = FALSE; - tio.fErrorChar = FALSE; - tio.fNull = FALSE; - tio.fRtsControl = RTS_CONTROL_ENABLE; - tio.fAbortOnError = FALSE; - tio.ByteSize = 8; - tio.Parity = NOPARITY; - tio.StopBits = ONESTOPBIT; - - if (!SetCommState (comport, &tio)) { - xCloseHandle(comport); - - /* - * Probably not a com port. Try it as a file. - */ -try_as_file: - magfile_in = xfopen(portname, create_ok ? "w+b" : "rb", MYNAME); + if (gbser_is_serial(portname)) { + if (serial_handle = gbser_init(portname), NULL != serial_handle) { + int rc; + if (rc = gbser_set_port(serial_handle, bitrate, 8, 0, 1), gbser_OK != rc) { + fatal(MYNAME ": Can't configure port\n"); + } + } + is_file = 0; + if (serial_handle == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", portname); + } + return 1; + } else { + /* Does this check for an error? */ + magfile_h = xfopen(portname, create_ok ? "w+b" : "rb", MYNAME); is_file = 1; icon_mapping = map330_icon_table; mag_cleanse = m330_cleanse; got_version = 1; return 0; } - - GetCommTimeouts (comport, &timeout); - /* We basically do single character reads and simulate line input - * mode, so these values are kind of fictional. - */ - timeout.ReadIntervalTimeout = 1000; - timeout.ReadTotalTimeoutMultiplier = 1000; - timeout.ReadTotalTimeoutConstant = 1000; - timeout.WriteTotalTimeoutMultiplier = 1000; - timeout.WriteTotalTimeoutConstant = 1000; - if (!SetCommTimeouts (comport, &timeout)) { - xCloseHandle (comport); - fatal(MYNAME ": set timeouts\n"); - } - return 1; } -static char * -termread(char *ibuf, int size) -{ - int i=0; - DWORD cnt; - - if (is_file) { - return fgets(ibuf, size, magfile_in); - } - - ibuf[i]='a'; - for(;i < size;i++) { - if (ReadFile (comport, &ibuf[i], 1, &cnt, NULL) != TRUE) - break; - if (cnt < 1) - return NULL; - if (ibuf[i] == '\n') - break; - } - ibuf[i] = 0; - return ibuf; -} - -static void -termwrite(char *obuf, int size) +static char *termread(char *ibuf, int size) { - DWORD len; - if (is_file) { - fwrite(obuf, size, 1, magfile_out); - return; - } - WriteFile (comport, obuf, size, &len, NULL); - if ((int) len != size) { - fatal(MYNAME ":. Wrote %d of %d bytes.\n", len, size); + return fgets(ibuf, size, magfile_h); + } else { + int rc; + rc = gbser_read_line(serial_handle, ibuf, size, 2000, 0x0a, 0x0d); + if (rc != gbser_OK) { + fatal(MYNAME ": Read error\n"); + } + return ibuf; } } +/* Though not documented in the protocol spec, if the unit itself + * wants to create a field containing a comma, it will encode it + * as 2C. We extrapolate that any 2 digit hex encoding may + * be valid. We don't do this in termread() since we need to do it + * after the scanf. This means we have to do it field-by-field + * basis. + * + * The buffer is modified in place and shortened by copying the remaining + * string including the terminator. + */ static void -termdeinit() +mag_dequote(char *ibuf) { - xCloseHandle(comport); -} - -#else - -#include -#include - -speed_t -mkspeed(unsigned br) -{ - switch (br) { - case 1200: return B1200; - case 2400: return B2400; - case 4800: return B4800; - case 9600: return B9600; - case 19200: return B19200; -#if defined B57600 - case 57600: return B57600; -#endif -#if defined B115200 - case 115200: return B115200; -#endif - default: return B4800; + char *esc = NULL; + + while ((esc = strchr (ibuf, 0x1b))) { + int nremains = strlen(esc); + if (nremains >= 3) { + static const char hex[16] = "0123456789ABCDEF"; + char *c1 = strchr(hex, esc[1]); + char *c2 = strchr(hex, esc[2]); + if (c1 && c2) { + int escv = (c1 - hex) * 16 + (c2 - hex); + *esc++ = escv; + /* buffers overlap */ + memmove(esc, esc+2, nremains - 2); + } + } } } - -static struct termios orig_tio; -static void -terminit(const char *portname, int create_ok) +static void +termwrite(char *obuf, int size) { - struct termios new_tio; - - magfile_in = xfopen(portname, "rb", MYNAME); - - is_file = !isatty(fileno(magfile_in)); if (is_file) { - icon_mapping = map330_icon_table; - mag_cleanse = m330_cleanse; - got_version = 1; - return; - } - - magfile_out = xfopen(portname, "w+b", MYNAME); - magfd = fileno(magfile_in); - - tcgetattr(magfd, &orig_tio); - new_tio = orig_tio; - new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR| - IGNCR|ICRNL|IXON); - new_tio.c_oflag &= ~OPOST; - new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - new_tio.c_cflag &= ~(CSIZE|PARENB); - new_tio.c_cflag |= CS8; - new_tio.c_cc[VTIME] = 10; - new_tio.c_cc[VMIN] = 0; - - cfsetospeed(&new_tio, mkspeed(bitrate)); - cfsetispeed(&new_tio, mkspeed(bitrate)); - tcsetattr(magfd, TCSAFLUSH, &new_tio); -} - -static void -termdeinit() -{ - if (!is_file) { - tcsetattr(magfd, TCSANOW, &orig_tio); + size_t nw; + if (nw = fwrite(obuf, 1, size, magfile_h), nw < (size_t) size) { + fatal(MYNAME ": Write error"); + } + } else { + int rc; + if (rc = gbser_write(serial_handle, obuf, size), rc < 0) { + fatal(MYNAME ": Write error"); + } } } -static char * -termread(char *ibuf, int size) -{ - return fgets(ibuf, size, magfile_in); -} - -static void -termwrite(char *obuf, int size) +static void termdeinit() { - fwrite(obuf, size, 1, magfile_out); + if (is_file) { + fclose(magfile_h); + magfile_h = NULL; + } else { + gbser_deinit(serial_handle); + serial_handle = NULL; + } } -#endif /* * Arg tables are doubled up so that -? can output appropriate help */ static arglist_t mag_sargs[] = { - {"baud", &bs, "Numeric value of bitrate (baud=4800)", NULL, - ARGTYPE_INT }, + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX }, {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"baud", &bs, "Numeric value of bitrate (baud=4800)", NULL, + ARGTYPE_INT, ARG_NOMINMAX }, {"noack", &noack, "Suppress use of handshaking in name of speed", - NULL, ARGTYPE_BOOL}, - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING }, - {"nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + ARG_TERMINATOR }; static arglist_t mag_fargs[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING }, - {0, 0, 0, 0, 0} + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX }, + {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + NULL, ARGTYPE_INT, ARG_NOMINMAX }, + ARG_TERMINATOR }; +/* + * The part of the serial init that's common to read and write. + */ static void -mag_rd_init(const char *portname) +mag_serial_init_common(const char *portname) { time_t now, later; - waypoint_read_count = 0; - if (bs) { - bitrate=atoi(bs); - } - - terminit(portname, 0); - if (!mkshort_handle) { - mkshort_handle = mkshort_new_handle(); + if (is_file) { + return; } - if (!noack) + mag_handoff(); + if (!noack && !suppress_ack) mag_handon(); now = current_time(); @@ -757,10 +685,8 @@ mag_rd_init(const char *portname) * commands. Time out on the side of caution. */ later = now + 6; - if (!is_file) { - got_version = 0; - mag_writemsg("PMGNCMD,VERSION"); - } + got_version = 0; + mag_writemsg("PMGNCMD,VERSION"); while (!got_version) { mag_readmsg(trkdata); @@ -770,7 +696,7 @@ mag_rd_init(const char *portname) } } - if (!is_file && (icon_mapping != gps315_icon_table)) { + if ((icon_mapping != gps315_icon_table)) { /* * The 315 can't handle this command, so we set a global * to ignore the NAK on it. @@ -779,6 +705,7 @@ mag_rd_init(const char *portname) mag_writemsg("PMGNCMD,NMEAOFF"); ignore_unable = 0; } + if (nukewpt) { /* The unit will send us an "end" message upon completion */ mag_writemsg("PMGNCMD,DELETE,WAYPOINT"); @@ -789,14 +716,77 @@ mag_rd_init(const char *portname) found_done = 0; } +} +static void +mag_rd_init_common(const char *portname) +{ + char *ext; + waypoint_read_count = 0; + + if (bs) { + bitrate=atoi(bs); + } + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + terminit(portname, 0); + mag_serial_init_common(portname); + QUEUE_INIT(&rte_wpt_tmp); + /* find the location of the tail of the path name, + * make a copy of it, then lop off the file extension + */ + + curfname = strrchr(portname, GB_PATHSEP); + if (curfname) { + curfname++; /* skip over path delimiter */ + } else { + curfname = portname; + } + + /* + * I'd rather not derive behaviour from filenames but since + * we can't otherwise tell if we should put a WPT on the route + * queue or the WPT queue in the presence of (-w -r -t) we + * divine a hint from the filename extension when we can. + */ + ext = strrchr(curfname, '.'); + if (ext) { + ext++; + if (0 == case_ignore_strcmp(ext, "upt")) { + extension_hint = WPTDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "log")) { + extension_hint = TRKDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "rte")) { + extension_hint = RTEDATAMASK; + } + } + return; } +static void +mag_rd_init(const char *portname) +{ + explorist = 0; + suppress_ack = 1; + mag_rd_init_common(portname); +} + +static void +magX_rd_init(const char *portname) +{ + explorist = 1; + mag_rd_init_common(portname); +} + static void mag_wr_init_common(const char *portname) { + suppress_ack = 0; if (bs) { bitrate=atoi(bs); } @@ -807,38 +797,13 @@ mag_wr_init_common(const char *portname) wptcmtcnt_max = MAXCMTCT ; } -#if __WIN32__ - if (!terminit(portname, 1)) { - is_file = 1; - } -#else - magfile_out = xfopen(portname, "w+b", MYNAME); - is_file = !isatty(fileno(magfile_out)); -#endif - if (!mkshort_handle) { mkshort_handle = mkshort_new_handle(); } - if (is_file) { - magfile_out = xfopen(portname, "w+b", MYNAME); - icon_mapping = map330_icon_table; - mag_cleanse = m330_cleanse; - got_version = 1; - } else { - /* - * This is a serial device. The line has to be open for - * reading and writing, so we let rd_init do the dirty work. - */ - if (magfile_out) { - fclose(magfile_out); - } -#if __WIN32__ - if (comport) { - xCloseHandle(comport); - } -#endif - mag_rd_init(portname); - } + + terminit(portname, 1); + mag_serial_init_common(portname); + QUEUE_INIT(&rte_wpt_tmp); } @@ -849,15 +814,24 @@ static void magX_wr_init(const char *portname) { wpt_len = 20; + explorist = 1; mag_wr_init_common(portname); setshort_length(mkshort_handle, wpt_len); + setshort_whitespace_ok(mkshort_handle, 1); } static void mag_wr_init(const char *portname) { + explorist = 0; wpt_len = 8; mag_wr_init_common(portname); + /* + * Whitespace is actually legal, but since waypoint name length is + * only 8 bytes, we'll conserve them. + */ + + setshort_whitespace_ok(mkshort_handle, 0); } static void @@ -865,16 +839,42 @@ mag_deinit(void) { mag_handoff(); termdeinit(); - if(magfile_in) - fclose(magfile_in); - magfile_in = NULL; if(mkshort_handle) - mkshort_del_handle(mkshort_handle); - mkshort_handle = NULL; + mkshort_del_handle(&mkshort_handle); waypt_flush(&rte_wpt_tmp); + + trk_head = NULL; } +/* + * I'm tired of arguing with scanf about optional fields . Detokenize + * an incoming string that may contain empty fields. + * + * Probably should be cleaned up and moved to common code, but + * making it deal with an arbitrary number of fields of arbitrary + * size is icky. We don't have to solve the general case here... + */ + +static char ifield[20][100]; +static +void parse_istring(char *istring) +{ + int f = 0; + int n,x; + while (istring[0]) { + char *fp = ifield[f]; + x = sscanf(istring, "%[^,]%n", fp, &n); + f++; + if (x) { + istring += n; + /* IF more in this string, skip delim */ + if (istring[0]) istring++; + } else { + istring ++; + } + } +} /* * Given an incoming track messages of the form: @@ -898,10 +898,21 @@ mag_trkparse(char *trkmsg) memset(&tm, 0, sizeof(tm)); - sscanf(trkmsg,"$PMGNTRK,%lf,%c,%lf,%c,%d,%c,%d.%d,A,,%d", - &latdeg,&latdir, - &lngdeg,&lngdir, - &alt,&altunits,&hms,&fracsecs,&dmy); + /* + * As some of the fields are optional, sscanf works badly + * for us. + */ + parse_istring(trkmsg); + latdeg = atof(ifield[1]); + latdir = ifield[2][0]; + lngdeg = atof(ifield[3]); + lngdir = ifield[4][0]; + alt = atof(ifield[5]); + altunits = ifield[6][0]; + sscanf(ifield[7], "%d.%d", &hms, &fracsecs); + /* Field 8 is constant */ + /* Field nine is optional track name */ + dmy = atoi(ifield[10]); tm.tm_sec = hms % 100; hms = hms / 100; @@ -946,12 +957,27 @@ mag_rteparse(char *rtemsg) static mag_rte_head *mag_rte_head; mag_rte_elem *rte_elem; char *p; + char *rte_name = NULL; descr[0] = 0; - +#if 0 + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); +#else sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", &frags,&frag,xbuf,&rtenum,&n); + /* Explorist has a route name here */ + if (explorist) { + char rten[1024]; + int n2; + sscanf(rtemsg + n, ",%[^,]%n", rten, &n2); + n += n2; + rte_name = xstrdup(rten); + } + +#endif + /* * This is the first component of a route. Allocate a new * queue head. @@ -999,6 +1025,7 @@ mag_rteparse(char *rtemsg) rte_head = route_head_alloc(); route_add_head(rte_head); rte_head->rte_num = rtenum; + rte_head->rte_name = xstrdup(rte_name); /* * It is quite feasible that we have 200 waypoints, @@ -1030,6 +1057,7 @@ mag_rteparse(char *rtemsg) } xfree(mag_rte_head); } + if (rte_name) xfree(rte_name); } const char * @@ -1042,6 +1070,7 @@ mag_find_descr_from_token(const char *token) } for (i = icon_mapping; i->token; i++) { + if (token[0] == 0) break; if (case_ignore_strcmp(token, i->token) == 0) return i->icon; } @@ -1097,6 +1126,8 @@ mag_wptparse(char *trkmsg) &alt,&altunits,shortname,descr); icone = strrchr(trkmsg, '*'); icons = strrchr(trkmsg, ',')+1; + + mag_dequote(descr); for (blah = icons ; blah < icone; blah++) icon_token[i++] = *blah; @@ -1120,8 +1151,8 @@ static void mag_read(void) { found_done = 0; - if (global_opts.masked_objective & TRKDATAMASK) { + magrxstate = mrs_handoff; if (!is_file) mag_writemsg("PMGNCMD,TRACK,2"); @@ -1130,7 +1161,9 @@ mag_read(void) } } + found_done = 0; if (global_opts.masked_objective & WPTDATAMASK) { + magrxstate = mrs_handoff; if (!is_file) mag_writemsg("PMGNCMD,WAYPOINT"); @@ -1139,7 +1172,9 @@ mag_read(void) } } + found_done = 0; if (global_opts.masked_objective & RTEDATAMASK) { + magrxstate = mrs_handoff; if (!is_file) { /* * serial routes require waypoint & routes @@ -1231,7 +1266,7 @@ mag_waypt_pr(const waypoint *waypointp) if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max)) odesc[0] = 0; - sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.lf,M,%-.*s,%-.46s,%s", + sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", lat, ilat < 0 ? 'S' : 'N', lon, ilon < 0 ? 'W' : 'E', waypointp->altitude == unknown_alt ? @@ -1299,7 +1334,7 @@ void mag_track_disp(const waypoint *waypointp) lon = (lon_deg * 100.0 + lon); lat = (lat_deg * 100.0 + lat); - sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.f,%c,%06d.%02d,A,,%06d", + sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.0f,%c,%06d.%02d,A,,%06d", lat, ilat < 0 ? 'S' : 'N', lon, ilon < 0 ? 'W' : 'E', waypointp->altitude == unknown_alt ? @@ -1370,11 +1405,17 @@ mag_route_trl(const route_head * rte) xfree(owpt); if ((tmp == &rte->waypoint_list) || ((i % 2) == 0)) { + char expbuf[1024]; thisline++; - - sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s,%s", + expbuf[0] = 0; + if (explorist) { + snprintf(expbuf, sizeof(expbuf), "%s,", + rte->rte_name ? rte->rte_name : ""); + } + sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s%s,%s", numlines, thisline, rte->rte_num ? rte->rte_num : route_out_count, + expbuf, buff1, buff2); mag_writemsg(obuff); @@ -1401,12 +1442,6 @@ mag_route_pr() static void mag_write(void) { - /* - * Whitespace is actually legal, but since waypoint name length is - * only 8 bytes, we'll conserve them. - */ - - setshort_whitespace_ok(mkshort_handle, 0); wptcmtcnt = 0; @@ -1440,7 +1475,8 @@ ff_vecs_t mag_svecs = { mag_read, mag_write, NULL, - mag_sargs + mag_sargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; ff_vecs_t mag_fvecs = { @@ -1453,7 +1489,8 @@ ff_vecs_t mag_fvecs = { mag_read, mag_write, NULL, - mag_fargs + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; /* @@ -1462,11 +1499,13 @@ ff_vecs_t mag_fvecs = { ff_vecs_t magX_fvecs = { ff_type_file, FF_CAP_RW_ALL, - mag_rd_init, + magX_rd_init, magX_wr_init, mag_deinit, mag_deinit, mag_read, mag_write, - NULL, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/main.c b/main.c index 01e0adaac..9fcfc7081 100644 --- a/main.c +++ b/main.c @@ -19,16 +19,105 @@ #include "defs.h" +#include "filterdefs.h" +#include "cet.h" +#include "cet_util.h" +#include "csv_util.h" +#include "inifile.h" #include -global_options global_opts; -const char gpsbabel_version[] = VERSION; +#define MYNAME "main" + +typedef struct arg_stack_s { + int argn; + int argc; + char **argv; + struct arg_stack_s *prev; +} arg_stack_t; + +static arg_stack_t +*push_args(arg_stack_t *stack, const int argn, const int argc, char *argv[]) +{ + arg_stack_t *res = xmalloc(sizeof(*res)); + + res->prev = stack; + res->argn = argn; + res->argc = argc; + res->argv = (char **)argv; + + return res; +} + +static arg_stack_t +*pop_args(arg_stack_t *stack, int *argn, int *argc, char **argv[]) +{ + arg_stack_t *res; + char **argv2 = *argv; + int i; + + if (stack == NULL) fatal("main: Invalid point in time to call 'pop_args'\n"); + + for (i = 0; i < *argc; i++) + xfree(argv2[i]); + xfree(*argv); + + *argn = stack->argn; + *argc = stack->argc; + *argv = stack->argv; + + res = stack->prev; + xfree(stack); + + return res; +} static void -usage(const char *pname, int shorter) +load_args(const char *filename, int *argc, char **argv[]) +{ + gbfile *fin; + char *str, *line = NULL; + int argc2; + char **argv2; + + fin = gbfopen(filename, "r", "main"); + while ((str = gbfgetstr(fin))) { + str = lrtrim(str); + if ((*str == '\0') || (*str == '#')) continue; + + if (line == NULL) line = xstrdup(str); + else { + char *tmp; + xasprintf(&tmp, "%s %s", line, str); + xfree(line); + line = tmp; + } + } + gbfclose(fin); + + argv2 = xmalloc(2 * sizeof(*argv2)); + argv2[0] = xstrdup(*argv[0]); + argc2 = 1; + + str = csv_lineparse(line, " ", "\"", 0); + while (str != NULL) { + argv2 = xrealloc(argv2, (argc2 + 2) * sizeof(*argv2)); + argv2[argc2] = xstrdup(str); + argc2++; + str = csv_lineparse(NULL, " ", "\"", 0); + } + xfree(line); + + argv2[argc2] = NULL; + + *argc = argc2; + *argv = argv2; +} + +static void +usage(const char *pname, int shorter ) { printf("GPSBabel Version %s. http://www.gpsbabel.org\n\n", - VERSION ); + gpsbabel_version ); printf( "Usage:\n" " %s [options] -i INTYPE -f INFILE -o OUTTYPE -F OUTFILE\n" @@ -43,19 +132,23 @@ usage(const char *pname, int shorter) " In the second form of the command, INFILE and OUTFILE are the\n" " first and second positional (non-option) arguments.\n" "\n" -" INTYPE and OUTTYPE must be one of the file types listed below, and\n" +" INTYPE and OUTTYPE must be one of the supported file types and\n" " may include options valid for that file type. For example:\n" " 'gpx', 'gpx,snlen=10' and 'ozi,snlen=10,snwhite=1'\n" " (without the quotes) are all valid file type specifications.\n" "\n" "Options:\n" +" -p Preferences file (gpsbabel.ini)\n" " -s Synthesize shortnames\n" " -r Process route information\n" " -t Process track information\n" " -w Process waypoint information [default]\n" +" -b Process command file (batch mode)\n" +" -c Character set for next operation\n" " -N No smart icons on output\n" " -x filtername Invoke filter (place between inputs and output) \n" " -D level Set debug level [%d]\n" +" -l Print GPSBabel builtin character sets and exit\n" " -h, -? Print detailed help and exit\n" " -V Print GPSBabel version and exit\n" "\n" @@ -75,7 +168,13 @@ usage(const char *pname, int shorter) } } - +static void +spec_usage( const char *vec ) { + printf( "\n" ); + disp_vec( vec ); + disp_filter_vec ( vec ); + printf( "\n" ); +} int main(int argc, char *argv[]) @@ -93,10 +192,19 @@ main(int argc, char *argv[]) int opt_version = 0; int did_something = 0; const char *prog_name = argv[0]; /* argv is modified during processing */ + queue *wpt_head_bak, *rte_head_bak, *trk_head_bak; /* #ifdef UTF8_SUPPORT */ + signed int wpt_ct_bak, rte_ct_bak, trk_ct_bak; /* #ifdef UTF8_SUPPORT */ + arg_stack_t *arg_stack = NULL; global_opts.objective = wptdata; global_opts.masked_objective = NOTHINGMASK; /* this makes the default mask behaviour slightly different */ + global_opts.charset = NULL; + global_opts.charset_name = NULL; + global_opts.inifile = NULL; + gpsbabel_now = time(NULL); /* gpsbabel startup-time */ + gpsbabel_time = current_time(); /* same like gpsbabel_now, but freezed to zero during testo */ + #ifdef DEBUG_MEM debug_mem_open(); debug_mem_output( "command line: " ); @@ -105,7 +213,11 @@ main(int argc, char *argv[]) } debug_mem_output( "\n" ); #endif + if (gpsbabel_time != 0) { /* within testo ? */ + global_opts.inifile = inifile_init(NULL, MYNAME); + } + cet_register(); waypt_init(); route_init(); @@ -117,7 +229,8 @@ main(int argc, char *argv[]) /* * Open-code getopts since POSIX-impaired OSes don't have one. */ - for (argn = 1; argn < argc; argn++) { + argn = 1; + while (argn < argc) { char *optarg; if (argv[argn][0] != '-') { @@ -128,12 +241,17 @@ main(int argc, char *argv[]) } if (argv[argn][1] == 'V' ) { - printf("\nGPSBabel Version %s\n\n", VERSION ); + printf("\nGPSBabel Version %s\n\n", gpsbabel_version ); exit(0); } if (argv[argn][1] == '?' || argv[argn][1] == 'h') { - usage(argv[0],0); + if ( argn < argc-1 ) { + spec_usage( argv[argn+1] ); + } + else { + usage(argv[0],0); + } exit(0); } @@ -144,12 +262,19 @@ main(int argc, char *argv[]) } switch (c) { + case 'c': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + cet_convert_init(optarg, 1); + break; case 'i': optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; ivecs = find_vec(optarg, &ivec_opts); break; case 'o': + if (ivecs == NULL) { + warning ("-o appeared before -i. This is probably not what you want to do.\n"); + } optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; ovecs = find_vec(optarg, &ovec_opts); @@ -167,27 +292,77 @@ main(int argc, char *argv[]) if (ivecs->rd_init == NULL) { fatal ("Format does not support reading.\n"); } + if (global_opts.masked_objective & POSNDATAMASK) { + did_something = 1; + break; + } /* simulates the default behaviour of waypoints */ if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; + + cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */ + ivecs->rd_init(fname); ivecs->read(); ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + did_something = 1; break; case 'F': optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; ofname = optarg; - if (ovecs) { + if (ovecs && (!(global_opts.masked_objective & POSNDATAMASK))) { /* simulates the default behaviour of waypoints */ if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; if (ovecs->wr_init == NULL) { fatal ("Format does not support writing.\n"); } + + cet_convert_init(ovecs->encode, ovecs->fixed_encode); + + wpt_ct_bak = -1; + rte_ct_bak = -1; + trk_ct_bak = -1; + rte_head_bak = trk_head_bak = NULL; + ovecs->wr_init(ofname); + + if (global_opts.charset != &cet_cs_vec_utf8) + { + /* + * Push and pop verbose_status so + * we don't get dual progress bars + * when doing characterset + * transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + waypt_backup(&wpt_ct_bak, &wpt_head_bak); + route_backup(&rte_ct_bak, &rte_head_bak); + track_backup(&trk_ct_bak, &trk_head_bak); + + cet_convert_strings(NULL, global_opts.charset, NULL); + global_opts.verbose_status = saved_status; + } + ovecs->write(); ovecs->wr_deinit(); + + cet_convert_deinit(); + + if (wpt_ct_bak != -1) waypt_restore(wpt_ct_bak, wpt_head_bak); + if (rte_ct_bak != -1) { + route_restore( rte_head_bak); + xfree( rte_head_bak ); + } + if (trk_ct_bak != -1) { + track_restore( trk_head_bak); + xfree( trk_head_bak ); + } } break; case 's': @@ -205,6 +380,10 @@ main(int argc, char *argv[]) global_opts.objective = rtedata; global_opts.masked_objective |= RTEDATAMASK; break; + case 'T': + global_opts.objective = posndata; + global_opts.masked_objective |= POSNDATAMASK; + break; case 'N': switch(argv[argn][2]) { case 'i': @@ -242,7 +421,7 @@ main(int argc, char *argv[]) * When debugging, announce version. */ if (global_opts.debug_level > 0) { - warning("GPSBabel Version: " VERSION "\n" ); + warning("GPSBabel Version: %s \n", gpsbabel_version ); } break; @@ -270,7 +449,35 @@ main(int argc, char *argv[]) case '?': usage(argv[0],0); exit(0); + case 'l': + cet_disp_character_set_names(stdout); + exit(0); + case 'p': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + inifile_done(global_opts.inifile); + if (!optarg || strcmp(optarg, "") == 0) /* from GUI to preserve inconsistent options */ + global_opts.inifile = NULL; + else + global_opts.inifile = inifile_init(optarg, MYNAME); + break; + case 'b': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + arg_stack = push_args(arg_stack, argn, argc, argv); + load_args(optarg, &argc, &argv); + if (argc == 0) + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + else + argn = 0; + break; + + default: + fatal("Unknown option '%s'.\n", argv[argn]); + break; } + + if ((argn+1 >= argc) && (arg_stack != NULL)) + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + argn++; } /* @@ -286,13 +493,26 @@ main(int argc, char *argv[]) did_something = 1; /* simulates the default behaviour of waypoints */ if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; + + cet_convert_init(ivecs->encode, 1); + ivecs->rd_init(argv[0]); ivecs->read(); ivecs->rd_deinit(); - if (argc == 2 && ovecs) { + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + if (argc == 2 && ovecs) + { + cet_convert_init(ovecs->encode, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + ovecs->wr_init(argv[1]); ovecs->write(); ovecs->wr_deinit(); + + cet_convert_deinit(); } } else if (argc) { @@ -300,15 +520,90 @@ main(int argc, char *argv[]) exit(0); } if (ovecs == NULL) + { + /* + * Push and pop verbose_status so we don't get dual + * progress bars when doing characterset transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + cet_convert_init(CET_CHARSET_ASCII, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); waypt_disp_all(waypt_disp); + global_opts.verbose_status = saved_status; + } + + /* + * This is very unlike the rest of our command sequence. + * If we're doing realtime position tracking, we enforce that + * we're not doing anything else and we just bounce between + * the special "read position" and "write position" vectors + * in our most recent vecs. + */ + if (global_opts.masked_objective & POSNDATAMASK) { + + if (!ivecs->position_ops.rd_position) { + fatal("Realtime tracking (-T) is not suppored by this input type.\n"); + } + + + if (ivecs->position_ops.rd_init) { + ivecs->position_ops.rd_init(fname); + } + + if (global_opts.masked_objective & ~POSNDATAMASK) { + fatal("Realtime tracking (-T) is exclusive of other modes.\n"); + } + + if (ovecs) { + if (!ovecs->position_ops.wr_init || + !ovecs->position_ops.wr_position || + !ovecs->position_ops.wr_deinit) { + fatal ("This output format does not support realtime positioning.\n"); + } + } + + while (1) { + posn_status status; + waypoint *wpt = ivecs->position_ops.rd_position(&status); + status.request_terminate = 0; + + if (status.request_terminate) { + if (wpt) { + waypt_free(wpt); + } + break; + } + if (wpt) { + if (ovecs) { + ovecs->position_ops.wr_init(ofname); + ovecs->position_ops.wr_position(wpt); + ovecs->position_ops.wr_deinit(); + } else { + /* Just print to screen */ + waypt_disp(wpt); + } + waypt_free(wpt); + } + } + if (ivecs->position_ops.rd_deinit) { + ivecs->position_ops.rd_deinit(); + } + if (ivecs->position_ops.wr_deinit) { + ivecs->position_ops.wr_deinit(); + } + } + if (!did_something) fatal ("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); + cet_deregister(); waypt_flush_all(); route_flush_all(); exit_vecs(); exit_filter_vecs(); + inifile_done(global_opts.inifile); #ifdef DEBUG_MEM debug_mem_close(); diff --git a/make-an1sym.pl b/make-an1sym.pl index 5af6814be..276699b2a 100644 --- a/make-an1sym.pl +++ b/make-an1sym.pl @@ -199,12 +199,12 @@ sub DoImage { "f276f6b3", "", # ??? "91d242c8", "Running", "8b0078db", "Transportation", - "0599f6c9", "Fishing", + "0599f6c9", "Fishing 2", "7389128c", "Automotive", "0362b593", "Cloudy", "f0717a94", "Partly Cloudy", "14486bbc", "Mostly Cloudy", - "7a258c70", "Tornado", + "7a258c70", "Hurricane", "eff260d4", "Lightning", "c3d70220", "Rain", # everything else is defined diff --git a/mapopolis.c b/mapopolis.c index 55e73bd76..151cc7d99 100644 --- a/mapopolis.c +++ b/mapopolis.c @@ -20,6 +20,7 @@ */ #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" @@ -67,7 +68,7 @@ struct record { static FILE *file_in; static FILE *file_out; static const char *out_fname; -static void *mkshort_handle; +static short_handle mkshort_handle; struct pdb *opdb; struct pdb_record *opdb_rec; @@ -97,7 +98,7 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } convert_rec0(struct record0 *rec0) @@ -164,13 +165,13 @@ decode(char *buf) be_read16(&rec->lon1d) / LONDIV2; vdata = (char *) rec + sizeof(*rec); - wpt_tmp->description = strdup(vdata); + wpt_tmp->description = xstrdup(vdata); vdata += strlen(wpt_tmp->description) + 1 + 6; while (*vdata == 0x40) vdata++; decode(vdata); - wpt_tmp->notes = strdup(vdata); + wpt_tmp->notes = xstrdup(vdata); vdata += strlen(wpt_tmp->notes) + 1; waypt_add(wpt_tmp); @@ -316,4 +317,8 @@ ff_vecs_t mapopolis_vecs = { wr_deinit, data_read, data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/mapsend.c b/mapsend.c index 40b7e97c1..90cb6aa63 100644 --- a/mapsend.c +++ b/mapsend.c @@ -1,7 +1,7 @@ /* Access Magellan Mapsend files. - Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002-2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,7 +27,8 @@ static FILE *mapsend_file_in; static FILE *mapsend_file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; +static short_handle wpt_handle; static int route_wp_count; static int mapsend_infile_version; @@ -35,9 +36,41 @@ static int trk_version = 30; #define MYNAME "mapsend" +static char *mapsend_opt_trkver = NULL; +#define MAPSEND_TRKVER_MIN 3 +#define MAPSEND_TRKVER_MAX 4 + +static +arglist_t mapsend_args[] = { + {"trkver", &mapsend_opt_trkver, + "MapSend version TRK file to generate (3,4)", + "4", ARGTYPE_INT, "3", "4" }, + ARG_TERMINATOR +}; + +static void +mapsend_init_opts(const char isReading) { /* 1=read, 2=write */ + int opt_trkver; + + /* read & write options here */ + + if (isReading) { + /* reading-only options here */ + } else { + /* writing-only options here */ + + // TRK MapSend version + opt_trkver = atoi(mapsend_opt_trkver); + if ((opt_trkver < MAPSEND_TRKVER_MIN) || (opt_trkver > MAPSEND_TRKVER_MAX)) + fatal(MYNAME ": Unsupported MapSend TRK version \"%s\"!\n", mapsend_opt_trkver); + trk_version = opt_trkver * 10; + } +} + static void mapsend_rd_init(const char *fname) { + mapsend_init_opts(1); mapsend_file_in = xfopen(fname, "rb", MYNAME); } @@ -83,7 +116,7 @@ my_fread4(void *ptr, FILE *stream) static size_t -my_fwrite4(int *ptr, FILE *stream) +my_fwrite4(void *ptr, FILE *stream) { int i = le_read32(ptr); return fwrite(&i, 4, 1, stream); @@ -92,8 +125,14 @@ my_fwrite4(int *ptr, FILE *stream) static void mapsend_wr_init(const char *fname) { + mapsend_init_opts(0); mapsend_file_out = xfopen(fname, "wb", MYNAME); mkshort_handle = mkshort_new_handle(); + + wpt_handle = mkshort_new_handle(); + setshort_whitespace_ok(wpt_handle, 1); + setshort_length(wpt_handle, 8); + route_wp_count = 0; } @@ -101,7 +140,8 @@ static void mapsend_wr_deinit(void) { fclose(mapsend_file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&wpt_handle); } static void @@ -265,7 +305,7 @@ mapsend_track_read(void) wpt_tmp->creation_time = time; wpt_tmp->centiseconds = centisecs; wpt_tmp->altitude = wpt_alt; - route_add_wpt(track_head, wpt_tmp); + track_add_wpt(track_head, wpt_tmp); } } @@ -335,14 +375,15 @@ mapsend_waypt_pr(const waypoint *waypointp) * them into the Mapsend file. */ - tmp = str_utf8_to_ascii(sn); + + tmp = mkshort(wpt_handle, sn); c = tmp ? strlen(tmp) : 0; fwrite(&c, 1, 1, mapsend_file_out); fwrite(tmp, c, 1, mapsend_file_out); if (tmp) xfree(tmp); - tmp = str_utf8_to_ascii(waypointp->description); + tmp = waypointp->description; if (tmp) c = strlen(tmp); else @@ -351,8 +392,6 @@ mapsend_waypt_pr(const waypoint *waypointp) if (c > 30) c = 30; fwrite(&c, 1, 1, mapsend_file_out); fwrite(tmp, c, 1, mapsend_file_out); - if (tmp) - xfree(tmp); /* #, icon, status */ n = ++cnt; @@ -475,12 +514,19 @@ void mapsend_track_hdr(const route_head * trk) char *tname; unsigned char c; int i; - mapsend_hdr hdr = {13, "4D533334 MS", "30", ms_type_track, {0}}; + mapsend_hdr hdr = {13, "4D533334 MS", "30", ms_type_track, {0, 0, 0}}; switch (trk_version) { case 20: verstring = "30"; break; case 30: verstring = "34"; break; - case 40: verstring = "36"; break; + case 40: + /* the signature seems to change with the versions, even though it + * shouldn't have according to the document. MapSend V4 doesn't + * like the old version. + */ + hdr.ms_signature[7] = '6'; + verstring = "36"; + break; default: fatal("Unknown track version.\n"); break; } @@ -517,6 +563,7 @@ void mapsend_track_disp(const waypoint * wpt) double dbl; int i; int t; + int f; int valid = 1; static int last_time; @@ -543,9 +590,16 @@ void mapsend_track_disp(const waypoint * wpt) dbl = -wpt->latitude; my_fwrite8(&dbl, mapsend_file_out); - /* altitude */ - i = (int) wpt->altitude; - my_fwrite4(&i, mapsend_file_out); + /* altitude + * in V4.0+ this field is a float, it was previously an int + */ + if (trk_version < 40) { + i = (int) wpt->altitude; + my_fwrite4(&i, mapsend_file_out); + } else { + f = (float) wpt->altitude; + my_fwrite4(&f, mapsend_file_out); + } /* time */ my_fwrite4(&t, mapsend_file_out); @@ -570,7 +624,7 @@ mapsend_track_write(void) static void mapsend_wpt_write(void) { - mapsend_hdr hdr = {13, {"4D533330 MS"}, {"30"}, ms_type_wpt, {0}}; + mapsend_hdr hdr = {13, {"4D533330 MS"}, {"30"}, ms_type_wpt, {0, 0, 0}}; int wpt_count = waypt_count(); int n = 0; @@ -613,5 +667,7 @@ ff_vecs_t mapsend_vecs = { mapsend_wr_deinit, mapsend_read, mapsend_wpt_write, - NULL + NULL, + mapsend_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/mapsource.c b/mapsource.c index 0ba7bd83b..01e486426 100644 --- a/mapsource.c +++ b/mapsource.c @@ -26,30 +26,31 @@ #include "defs.h" #include "garmin_tables.h" +#include "jeeps/gpsmath.h" #include static FILE *mps_file_in; static FILE *mps_file_out; static FILE *mps_file_temp; -static void *mkshort_handle; +static short_handle mkshort_handle; static int mps_ver_in = 0; static int mps_ver_out = 0; static int mps_ver_temp = 0; /* Temporary pathname used when merging gpsbabel output with an existing file */ -static char tempname[256]; -static char origname[256]; +static char *tempname; +static char *fin_name; static const waypoint *prevRouteWpt; /* Private queues of written out waypoints */ static queue written_wpt_head; static queue written_route_wpt_head; -static void *written_wpt_mkshort_handle; +static short_handle written_wpt_mkshort_handle; /* Private queue of read in waypoints assumed to be used only for routes */ static queue read_route_wpt_head; -static void *read_route_wpt_mkshort_handle; +static short_handle read_route_wpt_mkshort_handle; #define MPSDEFAULTWPTCLASS 0 #define MPSHIDDENROUTEWPTCLASS 8 @@ -68,53 +69,48 @@ static void *read_route_wpt_mkshort_handle; char *snlen = NULL; char *snwhiteopt = NULL; char *mpsverout = NULL; -char *mpsmergeout = NULL; +char *mpsmergeouts = NULL; +int mpsmergeout; char *mpsusedepth = NULL; char *mpsuseprox = NULL; static arglist_t mps_args[] = { - {"snlen", &snlen, "Length of generated shortnames", NULL, ARGTYPE_INT }, - { "snwhite", &snwhiteopt, "(0/1) Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL}, + {"snlen", &snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, {"mpsverout", &mpsverout, "Version of mapsource file to generate (3,4,5)", NULL, - ARGTYPE_INT }, - {"mpsmergeout", &mpsmergeout, "Merge output with existing file", - NULL, ARGTYPE_BOOL }, + ARGTYPE_INT, ARG_NOMINMAX }, + {"mpsmergeout", &mpsmergeouts, "Merge output with existing file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"mpsusedepth", &mpsusedepth, "Use depth values on output (default is ignore)", NULL, - ARGTYPE_BOOL }, + ARGTYPE_BOOL, ARG_NOMINMAX }, {"mpsuseprox", &mpsuseprox, "Use proximity values on output (default is ignore)", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; /* * A wrapper to ensure the doubles we fwrite are in correct endianness. */ -void -le_fwrite64(void *ptr, int sz, int ct, FILE *stream) +static void +le_fwrite_double(double d, FILE *stream) { unsigned char cbuf[8]; - - if ((sz != 8) || (ct != 1)) { - fatal(MYNAME ": Bad internal arguments to le_fwrite64.\n"); - } - - le_read64(cbuf, ptr); + le_write_double(cbuf,d); fwrite(cbuf, 8, 1, stream); } -void -le_fread64(void *ptr, int sz, int ct, FILE *stream) +static double +le_fread_double( FILE *stream) { unsigned char cbuf[8]; - fread(cbuf, 8, 1, stream); - le_read64(ptr, cbuf); + return le_read_double(cbuf); } static void @@ -170,65 +166,8 @@ mps_wpt_q_add(const queue *whichQueue, const waypoint *wpt) ENQUEUE_TAIL(whichQueue, &written_wpt->Q); } -const char * -mps_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format) -{ - icon_mapping_t *i; - - for (i = garmin_icon_table; i->icon; i++) { - switch (garmin_format) { - case MAPSOURCE: - if (icon == i->mpssymnum) - return i->icon; - break; - case PCX: - case GARMIN_SERIAL: - if (icon == i->pcxsymnum) - return i->icon; - break; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - return DEFAULTICONDESCR; -} - -int -mps_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) -{ - icon_mapping_t *i; - int def_icon = DEFAULTICONVALUE; - int n; - - if (!desc) - return def_icon; - - /* - * If we were given a numeric icon number as a description - * (i.e. 8255), just return that. - */ - n = atoi(desc); - if (n) { - return n; - } - - for (i = garmin_icon_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - switch (garmin_format) { - case MAPSOURCE: - return i->mpssymnum; - case PCX: - case GARMIN_SERIAL: - return i->pcxsymnum; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - } - return def_icon; -} - -int mps_converted_icon_number(const int icon_num, const int mpsver, garmin_formats_e garmin_format) +static int +mps_converted_icon_number(const int icon_num, const int mpsver, garmin_formats_e garmin_format) { int def_icon = DEFAULTICONVALUE; @@ -287,7 +226,7 @@ mps_rd_deinit(void) { fclose(mps_file_in); if ( read_route_wpt_mkshort_handle ) { - mkshort_del_handle( read_route_wpt_mkshort_handle ); + mkshort_del_handle( &read_route_wpt_mkshort_handle ); } /* flush the "private" queue of waypoints read for routes */ mps_wpt_q_deinit(&read_route_wpt_head); @@ -296,10 +235,15 @@ mps_rd_deinit(void) static void mps_wr_init(const char *fname) { + fin_name = xstrdup(fname); + if (mpsmergeouts) { + mpsmergeout = atoi(mpsmergeouts); + } + if (mpsmergeout) { mps_file_out = xfopen(fname, "rb", MYNAME); if (mps_file_out == NULL) { - mpsmergeout = NULL; + mpsmergeout = 0; } else { fclose(mps_file_out); @@ -309,14 +253,13 @@ mps_wr_init(const char *fname) /* create a temporary name based on a random char and the existing name */ /* then test if it already exists, if so try again with another rand num */ /* yeah, yeah, so there's probably a library function for this */ - sprintf(tempname, "%s.%08x", fname, rand()); + xasprintf(&tempname, "%s.%08x", fname, rand()); mps_file_temp = fopen(tempname, "rb"); if (mps_file_temp == NULL) break; fclose(mps_file_temp); } rename(fname, tempname); mps_file_temp = xfopen(tempname, "rb", MYNAME); - strcpy(origname, fname); /* save in case we need to revert the renamed file */ } } @@ -336,14 +279,16 @@ mps_wr_deinit(void) if (mpsmergeout) { fclose(mps_file_temp); remove(tempname); + xfree(tempname); } if ( written_wpt_mkshort_handle ) { - mkshort_del_handle( written_wpt_mkshort_handle ); + mkshort_del_handle( &written_wpt_mkshort_handle ); } /* flush the "private" queue of waypoints written */ mps_wpt_q_deinit(&written_wpt_head); mps_wpt_q_deinit(&written_route_wpt_head); + xfree(fin_name); } /* @@ -471,7 +416,8 @@ mps_mapsegment_r(FILE *mps_file, int mps_ver) { int reclen; - /* At the moment we're not doing anything with map segments, but here's the template code as if we were +#if 0 + /* At the moment we're not doing anything with map segments, but here's the template code as if we were */ char hdr[100]; fread(&CDid, 4, 1, mps_file); reclen = le_read32(&CDid); @@ -484,6 +430,7 @@ mps_mapsegment_r(FILE *mps_file, int mps_ver) mps_readstr(mps_file, CDAreaName, sizeof(CDAreaName)); fread(hdr, 4, 1, mps_file); /* trailing long value */ +#endif fseek(mps_file, -5, SEEK_CUR); fread(&reclen, 4, 1, mps_file); @@ -554,6 +501,7 @@ mps_waypoint_r(FILE *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpscla int lat; int lon; int icon; + int dynamic; waypoint *thisWaypoint = NULL; double mps_altitude = unknown_alt; @@ -582,22 +530,22 @@ mps_waypoint_r(FILE *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpscla fread(tbuf, 1, 1, mps_file); /* altitude validity */ if (tbuf[0] == 1) { - le_fread64(&mps_altitude,sizeof(mps_altitude),1,mps_file); + mps_altitude = le_fread_double(mps_file); } else { mps_altitude = unknown_alt; - le_fread64(tbuf,sizeof(mps_altitude),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } mps_readstr(mps_file, wptdesc, sizeof(wptdesc)); fread(tbuf, 1, 1, mps_file); /* proximity validity */ if (tbuf[0] == 1) { - le_fread64(&mps_proximity,sizeof(mps_proximity),1,mps_file); + mps_proximity = le_fread_double(mps_file); } else { mps_proximity = unknown_alt; - le_fread64(tbuf,sizeof(mps_proximity),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } fread(tbuf, 4, 1, mps_file); /* display flag */ @@ -613,11 +561,11 @@ mps_waypoint_r(FILE *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpscla fread(tbuf, 1, 1, mps_file); /* depth validity */ if (tbuf[0] == 1) { - le_fread64(&mps_depth,sizeof(mps_depth),1,mps_file); + mps_depth = le_fread_double( mps_file ); } else { mps_depth = unknown_alt; - le_fread64(tbuf,sizeof(mps_depth),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } if ((mps_ver == 4) || (mps_ver == 5)) { @@ -631,14 +579,15 @@ mps_waypoint_r(FILE *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpscla thisWaypoint->shortname = xstrdup(wptname); thisWaypoint->description = xstrdup(wptdesc); thisWaypoint->notes = xstrdup(wptnotes); - thisWaypoint->latitude = lat / 2147483648.0 * 180.0; - thisWaypoint->longitude = lon / 2147483648.0 * 180.0; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); thisWaypoint->altitude = mps_altitude; thisWaypoint->proximity = mps_proximity; thisWaypoint->depth = mps_depth; /* might need to change this to handle version dependent icon handling */ - thisWaypoint->icon_descr = mps_find_desc_from_icon_number(icon, MAPSOURCE); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(icon, MAPSOURCE, &dynamic); + thisWaypoint->wpt_flags.icon_descr_is_dynamic = dynamic; /* The following Now done elsewhere since it can be useful to read in and perhaps not add to the list */ @@ -656,10 +605,9 @@ mps_waypoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt, const int isRou { unsigned char hdr[100]; int reclen; - int lat = wpt->latitude / 180.0 * 2147483648.0; - int lon = wpt->longitude / 180.0 * 2147483648.0; - int icon; - char *src; + int lat, lon; + int icon; + char *src = ""; /* default to empty string */ char *ident; char *ascii_description; char zbuf[25]; @@ -671,6 +619,9 @@ mps_waypoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt, const int isRou double mps_proximity = (mpsuseprox ? wpt->proximity : unknown_alt); double mps_depth = (mpsusedepth ? wpt->depth : unknown_alt); + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if(wpt->description) src = wpt->description; if(wpt->notes) src = wpt->notes; ident = global_opts.synthesize_shortnames ? @@ -681,16 +632,16 @@ mps_waypoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt, const int isRou memset(ffbuf, 0xff, sizeof(ffbuf)); /* might need to change this to handle version dependent icon handling */ - icon = mps_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { - icon = mps_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); } icon = mps_converted_icon_number(icon, mps_ver, MAPSOURCE); /* two NULL (0x0) bytes at end of each string */ - ascii_description = wpt->description ? str_utf8_to_ascii(wpt->description) : xstrdup(""); + ascii_description = wpt->description ? xstrdup(wpt->description) : xstrdup(""); reclen = strlen(ident) + strlen(ascii_description) + 2; if ((mps_ver == 4) || (mps_ver == 5)) { /* v4.06 & V5.0*/ @@ -747,7 +698,7 @@ mps_waypoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt, const int isRou else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_altitude, 8 , 1, mps_file); + le_fwrite_double( mps_altitude, mps_file ); } if (wpt->description) fputs(ascii_description, mps_file); fwrite(zbuf, 1, 1, mps_file); /* NULL termination */ @@ -760,7 +711,7 @@ mps_waypoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt, const int isRou else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_proximity, 8 , 1, mps_file); + le_fwrite_double( mps_proximity, mps_file ); } le_write32(&display, display); @@ -782,7 +733,7 @@ mps_waypoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt, const int isRou else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_depth, 8 , 1, mps_file); + le_fwrite_double(mps_depth, mps_file); } fwrite(zbuf, 2, 1, mps_file); /* unknown */ @@ -916,7 +867,7 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte) char wptname[MPSNAMEBUFFERLEN]; int lat; int lon; - short int rte_autoname = 0; + char rte_autoname; int interlinkStepCount; int thisInterlinkStep; unsigned int mpsclass; @@ -935,35 +886,38 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte) fprintf(stderr, "mps_route_r: reading route %s\n", rtename); #endif - fread(&rte_autoname, 2, 1, mps_file); /* autoname flag */ - rte_autoname = le_read16(&rte_autoname); + fread(&rte_autoname, 1, 1, mps_file); /* autoname flag */ - fread(&lat, 4, 1, mps_file); - fread(&lon, 4, 1, mps_file); - lat = le_read32(&lat); /* max lat of whole route */ - lon = le_read32(&lon); /* max lon of whole route */ + fread(tbuf, 1, 1, mps_file); /* skip min/max values */ + if (tbuf[0] == 0) { - fread(tbuf, 1, 1, mps_file); /* altitude validity */ - if (tbuf[0] == 1) { - le_fread64(&mps_altitude,sizeof(mps_altitude),1,mps_file); /* max alt of the whole route */ - } - else { - mps_altitude = unknown_alt; - le_fread64(tbuf,sizeof(mps_altitude),1, mps_file); - } + fread(&lat, 4, 1, mps_file); + fread(&lon, 4, 1, mps_file); + lat = le_read32(&lat); /* max lat of whole route */ + lon = le_read32(&lon); /* max lon of whole route */ - fread(&lat, 4, 1, mps_file); - fread(&lon, 4, 1, mps_file); - lat = le_read32(&lat); /* min lat of whole route */ - lon = le_read32(&lon); /* min lon of whole route */ + fread(tbuf, 1, 1, mps_file); /* altitude validity */ + if (tbuf[0] == 1) { + mps_altitude = le_fread_double(mps_file); + } + else { + mps_altitude = unknown_alt; + fseek( mps_file, 8, SEEK_CUR ); + } - fread(tbuf, 1, 1, mps_file); /* altitude validity */ - if (tbuf[0] == 1) { - le_fread64(&mps_altitude,sizeof(mps_altitude),1,mps_file); /* min alt of the whole route */ - } - else { - mps_altitude = unknown_alt; - le_fread64(tbuf,sizeof(mps_altitude),1, mps_file); + fread(&lat, 4, 1, mps_file); + fread(&lon, 4, 1, mps_file); + lat = le_read32(&lat); /* min lat of whole route */ + lon = le_read32(&lon); /* min lon of whole route */ + + fread(tbuf, 1, 1, mps_file); /* altitude validity */ + if (tbuf[0] == 1) { + mps_altitude = le_fread_double(mps_file); + } + else { + mps_altitude = unknown_alt; + fseek( mps_file, 8, SEEK_CUR ); + } } fread(&rte_count, 4, 1, mps_file); /* number of waypoints in route */ @@ -1040,11 +994,11 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte) fread(tbuf, 1, 1, mps_file); /* altitude validity */ if (tbuf[0] == 1) { - le_fread64(&mps_altitude,sizeof(mps_altitude),1,mps_file); + mps_altitude = le_fread_double(mps_file); } else { mps_altitude = unknown_alt; - le_fread64(tbuf,sizeof(mps_altitude),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there @@ -1067,8 +1021,8 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte) #endif thisWaypoint = waypt_new(); thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->latitude = lat / 2147483648.0 * 180.0; - thisWaypoint->longitude = lon / 2147483648.0 * 180.0; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); thisWaypoint->altitude = mps_altitude; thisWaypoint->depth = mps_depth; } @@ -1088,11 +1042,11 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte) fread(tbuf, 1, 1, mps_file); /* altitude validity */ if (tbuf[0] == 1) { - le_fread64(&mps_altitude,sizeof(mps_altitude),1,mps_file); + mps_altitude = le_fread_double( mps_file ); } else { mps_altitude = unknown_alt; - le_fread64(tbuf,sizeof(mps_altitude),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } } @@ -1157,8 +1111,8 @@ mps_route_r(FILE *mps_file, int mps_ver, route_head **rte) /* should never reach here, but we do need a fallback position */ thisWaypoint = waypt_new(); thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->latitude = lat / 2147483648.0 * 180.0; - thisWaypoint->longitude = lon / 2147483648.0 * 180.0; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); thisWaypoint->altitude = mps_altitude; } } @@ -1181,11 +1135,11 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte) char *rname; char hdr[20]; char zbuf[20]; - char *src; + char *src = ""; char *ident; waypoint *testwpt; - time_t uniqueValue; + time_t uniqueValue = 0; int allWptNameLengths; double maxlat=-90.0; @@ -1241,7 +1195,7 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte) /* route name */ if (!rte->rte_name) { - sprintf(hdr, "Route%04x", uniqueValue); + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); rname = xstrdup(hdr); } else @@ -1285,8 +1239,8 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte) hdr[2] = 0; /* MSB of don't autoname */ fwrite(hdr, 3, 1, mps_file); /* NULL string terminator + route autoname flag */ - lat = maxlat / 180.0 * 2147483648.0; - lon = maxlon / 180.0 * 2147483648.0; + lat = GPS_Math_Deg_To_Semi(maxlat); + lon = GPS_Math_Deg_To_Semi(maxlon); le_write32(&lat, lat); le_write32(&lon, lon); @@ -1300,11 +1254,11 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&maxalt, 8 , 1, mps_file); + le_fwrite_double(maxalt, mps_file); } - lat = minlat / 180.0 * 2147483648.0; - lon = minlon / 180.0 * 2147483648.0; + lat = GPS_Math_Deg_To_Semi(minlat); + lon = GPS_Math_Deg_To_Semi(minlon); le_write32(&lat, lat); le_write32(&lon, lon); @@ -1319,7 +1273,7 @@ mps_routehdr_w(FILE *mps_file, int mps_ver, const route_head *rte) hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&minalt, 8 , 1, mps_file); + le_fwrite_double(minalt, mps_file); } le_write32(&rte_datapoints, rte_datapoints); @@ -1346,7 +1300,7 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt) int lon; char zbuf[20]; char ffbuf[20]; - char *src; + char *src = ""; char *ident; int reclen; @@ -1370,8 +1324,8 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt) fwrite(&reclen, 4, 1, mps_file); /* output end point 1 */ - lat = prevRouteWpt->latitude / 180.0 * 2147483648.0; - lon = prevRouteWpt->longitude / 180.0 * 2147483648.0; + lat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + lon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); le_write32(&lat, lat); le_write32(&lon, lon); @@ -1385,12 +1339,12 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_altitude, 8 , 1, mps_file); + le_fwrite_double(mps_altitude, mps_file ); } /* output end point 2 */ - lat = rtewpt->latitude / 180.0 * 2147483648.0; - lon = rtewpt->longitude / 180.0 * 2147483648.0; + lat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + lon = GPS_Math_Deg_To_Semi(rtewpt->longitude); le_write32(&lat, lat); le_write32(&lon, lon); @@ -1404,25 +1358,25 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_altitude, 8 , 1, mps_file); + le_fwrite_double(mps_altitude, mps_file); } if (rtewpt->latitude > prevRouteWpt->latitude) { - maxlat = rtewpt->latitude / 180.0 * 2147483648.0; - minlat = prevRouteWpt->latitude / 180.0 * 2147483648.0; + maxlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + minlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); } else { - minlat = rtewpt->latitude / 180.0 * 2147483648.0; - maxlat = prevRouteWpt->latitude / 180.0 * 2147483648.0; + minlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + maxlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); } if (rtewpt->longitude > prevRouteWpt->longitude) { - maxlon = rtewpt->longitude / 180.0 * 2147483648.0; - minlon = prevRouteWpt->longitude / 180.0 * 2147483648.0; + maxlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + minlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); } else { - minlon = rtewpt->longitude / 180.0 * 2147483648.0; - maxlon = prevRouteWpt->longitude / 180.0 * 2147483648.0; + minlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + maxlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); } if (rtewpt->altitude != unknown_alt) maxalt = rtewpt->altitude; @@ -1449,7 +1403,7 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&maxalt, 8 , 1, mps_file); + le_fwrite_double(maxalt, mps_file); } /* output min coords of the link */ @@ -1465,7 +1419,7 @@ mps_routedatapoint_w(FILE *mps_file, int mps_ver, const waypoint *rtewpt) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&minalt, 8 , 1, mps_file); + le_fwrite_double(minalt, mps_file ); } } @@ -1600,11 +1554,11 @@ mps_track_r(FILE *mps_file, int mps_ver, route_head **trk) fread(tbuf, 1, 1, mps_file); /* altitude validity */ if (tbuf[0] == 1) { - le_fread64(&mps_altitude,sizeof(mps_altitude),1,mps_file); + mps_altitude = le_fread_double( mps_file ); } else { mps_altitude = unknown_alt; - le_fread64(tbuf,sizeof(mps_altitude),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } fread(tbuf, 1, 1, mps_file); /* date/time validity */ @@ -1617,21 +1571,21 @@ mps_track_r(FILE *mps_file, int mps_ver, route_head **trk) fread(tbuf, 1, 1, mps_file); /* depth validity */ if (tbuf[0] == 1) { - le_fread64(&mps_depth,sizeof(mps_depth),1,mps_file); + mps_depth = le_fread_double(mps_file ); } else { mps_depth = unknown_alt; - le_fread64(tbuf,sizeof(mps_depth),1, mps_file); + fseek( mps_file, 8, SEEK_CUR ); } thisWaypoint = waypt_new(); - thisWaypoint->latitude = lat / 2147483648.0 * 180.0; - thisWaypoint->longitude = lon / 2147483648.0 * 180.0; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); thisWaypoint->creation_time = le_read32(&dateTime); thisWaypoint->centiseconds = 0; thisWaypoint->altitude = mps_altitude; thisWaypoint->depth = mps_depth; - route_add_wpt(track_head, thisWaypoint); + track_add_wpt(track_head, thisWaypoint); } /* while (trk_count--) */ @@ -1653,7 +1607,7 @@ mps_trackhdr_w(FILE *mps_file, int mps_ver, const route_head *trk) char *tname; char hdr[20]; waypoint *testwpt; - time_t uniqueValue; + time_t uniqueValue = 0; queue *elem, *tmp; @@ -1674,7 +1628,7 @@ mps_trackhdr_w(FILE *mps_file, int mps_ver, const route_head *trk) /* track name */ if (!trk->rte_name) { - sprintf(hdr, "Track%04x", uniqueValue); + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); tname = xstrdup(hdr); } else @@ -1723,14 +1677,16 @@ static void mps_trackdatapoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt) { unsigned char hdr[10]; - int lat = wpt->latitude / 180.0 * 2147483648.0; - int lon = wpt->longitude / 180.0 * 2147483648.0; + int lat, lon; time_t t = wpt->creation_time; char zbuf[10]; double mps_altitude = wpt->altitude; double mps_depth = (mpsusedepth ? wpt->depth : unknown_alt); + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + memset(zbuf, 0, sizeof(zbuf)); le_write32(&lat, lat); @@ -1744,7 +1700,7 @@ mps_trackdatapoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_altitude, 8 , 1, mps_file); + le_fwrite_double(mps_altitude, mps_file); } if (t > 0) { /* a valid time is assumed to > 0 */ @@ -1763,7 +1719,7 @@ mps_trackdatapoint_w(FILE *mps_file, int mps_ver, const waypoint *wpt) else { hdr[0] = 1; fwrite(hdr, 1 , 1, mps_file); - le_fwrite64(&mps_depth, 8 , 1, mps_file); + le_fwrite_double(mps_depth, mps_file ); } } @@ -1907,7 +1863,8 @@ mps_write(void) char recType; int reclen; - int reclen2; + /* TODO: This kills a compiler warning but I'm not sure it's right */ + int reclen2 = 0; unsigned int tocopy; unsigned int block; @@ -1916,10 +1873,7 @@ mps_write(void) unsigned char copybuf[8192]; - if (snlen) - short_length = atoi(snlen); - else - short_length = 10; + short_length = atoi(snlen); if (mpsmergeout) { /* need to skip over the merging header and test merge version */ @@ -1932,8 +1886,8 @@ mps_write(void) /* then delete the "real" file and rename the temporarily renamed file back */ fclose(mps_file_temp); fclose(mps_file_out); - remove(origname); - rename(tempname,origname); + remove(fin_name); + rename(tempname, fin_name); fatal (MYNAME ": merge source version is %d, requested out version is %d\n", mps_ver_temp, atoi(mpsverout)); } } @@ -2165,7 +2119,7 @@ mps_write(void) } else mps_mapsetname_w(mps_file_out, mps_ver_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } @@ -2179,5 +2133,6 @@ ff_vecs_t mps_vecs = { mps_read, mps_write, NULL, - mps_args + mps_args, + CET_CHARSET_MS_ANSI /* CET-REVIEW */ }; diff --git a/mingw/Makefile b/mingw/Makefile index 3285ce2cb..32837c31c 100644 --- a/mingw/Makefile +++ b/mingw/Makefile @@ -1,12 +1,13 @@ CC=/usr/local/cross-tools/bin/i386-mingw32msvc-gcc VPATH=..:../shapelib -FILES=gpsbabel.exe libexpat.dll ../win32/GPSBabelGUI.exe ../README* ../style/README.style ../COPYING +FILES=gpsbabel.exe libexpat.dll ../win32/GPSBabelGUI.exe ../win32/gui-2/README.gui \ + ../README* ../style/README.style ../COPYING ../readme.html gpsbabel.exe: wintesto.cmd include ../Makefile -CFLAGS=-Iinclude -I../coldsync -O $(INHIBIT_USB) +CFLAGS=-Iinclude -I../coldsync -O $(INHIBIT_USB) $(EXTRA_CFLAGS) # # Must define empty (don't comment out the whole line) if you want to # override INHIBIT_USB from the parent Makefile. diff --git a/mingw/libw/README b/mingw/libw/README new file mode 100644 index 000000000..281bcd8f8 --- /dev/null +++ b/mingw/libw/README @@ -0,0 +1 @@ +This is libexpat compiled with wchar_t support. diff --git a/mingw/libw/libexpat.a b/mingw/libw/libexpat.a new file mode 100644 index 0000000000000000000000000000000000000000..7c0f79f54eb68cc8beef317e089a492ddc590b6b GIT binary patch literal 51328 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 OwK1x#AZz8=8umYS0vyEv literal 0 HcmV?d00001 diff --git a/mingw/mkwintesto.c b/mingw/mkwintesto.c index 661fcb827..cd87679db 100644 --- a/mingw/mkwintesto.c +++ b/mingw/mkwintesto.c @@ -31,7 +31,7 @@ #include #include -#define LINELENGTH 200 +#define LINELENGTH 256 #define MYNAME "MkWinTesto" /* ------------------------------------------------------------------------------------ */ @@ -135,6 +135,7 @@ int argc, f_outputLine(pfTestoOut, "REM Simple Windows NT/2000/XP .cmd version of GPSBabel testo script"); f_outputLine(pfTestoOut, "REM"); f_outputLine(pfTestoOut, ""); + f_outputLine(pfTestoOut, "SET GPSBABEL_FREEZE_TIME=y"); f_outputLine(pfTestoOut, "SET TMPDIR=%TEMP%\\WINTESTO"); f_outputLine(pfTestoOut, "MKDIR %TMPDIR% 2>NUL:"); f_outputLine(pfTestoOut, ""); @@ -150,8 +151,8 @@ int argc, f_outputLine(pfTestoOut, "FOR /f \"delims=\" %%a IN ('fc %PARAM1% %PARAM2%') DO IF \"x%%a\"==\"xFC: no differences encountered\" GOTO :EOF"); f_outputLine(pfTestoOut, "REM Show the first 5 lines of difference"); f_outputLine(pfTestoOut, "fc %1 /LB5 %PARAM1% %PARAM2%"); - f_outputLine(pfTestoOut, "ECHO %* are not the same (first 5 differences above) - pausing. ^C to quit if required"); - f_outputLine(pfTestoOut, "PAUSE"); + f_outputLine(pfTestoOut, "if errorlevel 1 ECHO %* are not the same (first 5 differences above) - pausing. ^C to quit if required"); + f_outputLine(pfTestoOut, "if errorlevel 1 PAUSE"); f_outputLine(pfTestoOut, "GOTO :EOF"); f_outputLine(pfTestoOut, ""); f_outputLine(pfTestoOut, "REM =================================="); @@ -320,10 +321,21 @@ int argc, iTranslateQuotes = 1; iQuoteCount = 1; } + /* Is this one of the test sequences where we prepare some data? */ + if (strncmp("cat ",acLineIn,4) == 0) { + if (iEchoLevel > 0) { + f_outputLine(pfTestoOut, "@echo off"); + f_outputLine(pfTestoOut, "@echo."); + iEchoLevel = 0; + } + iStart = 4; + strcat(acLineOut, "TYPE "); + iTarget = 5; + } /* Is this one of the test sequences where we prepare some data by using sed? */ /* we only cater for sed that removes lines - this is only windows after all */ - if (strncmp("sed '/^L",acLineIn,8) == 0) { - pcTerm = strstr(acLineIn+8,"/d'"); + if (strncmp("sed '/",acLineIn,6) == 0) { + pcTerm = strstr(acLineIn+6,"/d'"); /* Did we find a terminator in the string? */ if ((pcTerm != NULL) && ((pcTerm - acLineIn) < LINELENGTH)) { @@ -332,10 +344,10 @@ int argc, f_outputLine(pfTestoOut, "@echo."); iEchoLevel = 0; } - iStart = 8; - strcat(acLineOut, "FINDSTR /V \""); - iTarget = 12; - for (iThisChar=8; iThisChar<(pcTerm - acLineIn); iThisChar++) { + iStart = 6; + strcat(acLineOut, "FINDSTR /V /R /C:\""); + iTarget = 18; + for (iThisChar=6; iThisChar<(pcTerm - acLineIn); iThisChar++) { acLineOut[iTarget++] = acLineIn[iStart++]; } acLineOut[iTarget++] = (char)0; diff --git a/mingw/wintesto.cmd b/mingw/wintesto.cmd index 9afc3aeae..1d575898f 100644 --- a/mingw/wintesto.cmd +++ b/mingw/wintesto.cmd @@ -3,6 +3,7 @@ REM REM Simple Windows NT/2000/XP .cmd version of GPSBabel testo script REM +SET GPSBABEL_FREEZE_TIME=y SET TMPDIR=%TEMP%\WINTESTO MKDIR %TMPDIR% 2>NUL: @@ -18,8 +19,8 @@ FOR %%A IN (%3) DO IF "d--------"=="%%~aA" SET PARAM2=%3\* FOR /f "delims=" %%a IN ('fc %PARAM1% %PARAM2%') DO IF "x%%a"=="xFC: no differences encountered" GOTO :EOF REM Show the first 5 lines of difference fc %1 /LB5 %PARAM1% %PARAM2% -ECHO %* are not the same (first 5 differences above) - pausing. ^C to quit if required -PAUSE +if errorlevel 1 ECHO %* are not the same (first 5 differences above) - pausing. ^C to quit if required +if errorlevel 1 PAUSE GOTO :EOF REM ================================== @@ -47,6 +48,8 @@ REM ================================== :REALSTART +REM Turn on GNU libc instrumentation. + SET PNAME=.\gpsbabel IF NOT EXIST %PNAME%.EXE ECHO Can't find %PNAME%&& GOTO :EOF @@ -54,7 +57,16 @@ IF NOT EXIST %PNAME%.EXE ECHO Can't find %PNAME%&& GOTO :EOF - +REM Some formats are just too boring to test. The ones that +REM are xcsv include +REM garmin301 +REM garmin_poi +REM gpsdrivetrack +REM nima +REM mapconverter +REM geonet +REM saplus +REM s_and_t REM Geocaching .loc DEL %TMPDIR%\gl.loc @echo on @@ -100,6 +112,18 @@ DEL %TMPDIR%\gl.gpx %TMPDIR%\gpx.gpx @echo. CALL :COMPARE %TMPDIR%\gpx.gpx %TMPDIR%\gu.wpt +REM GTM +DEL %TMPDIR%\gl.gpx %TMPDIR%\gpx.gpx +@echo on +@echo Testing... +%PNAME% -i gtm -f reference\sample.gtm -o gpx -F %TMPDIR%\gtm1.gpx +%PNAME% -i gpx -f %TMPDIR%\gtm1.gpx -o gtm -F %TMPDIR%\gtm.gtm +%PNAME% -i gtm -f %TMPDIR%\gtm.gtm -o gpx -F %TMPDIR%\gtm2.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gtm1.gpx %TMPDIR%\gtm2.gpx +CALL :COMPARE %TMPDIR%\gtm.gtm reference\sample.gtm + REM Magellan Mapsend DEL %TMPDIR%\mm.mapsend %TMPDIR%\mm.gps @echo on @@ -197,8 +221,17 @@ DEL %TMPDIR%\mm.pcx %TMPDIR%\pcx.gps @echo off @echo. CALL :COMPARE %TMPDIR%\mm.gps %TMPDIR%\gu.wpt +@echo on +@echo Testing... +%PNAME% -t -i gpx -f reference\track\tracks.gpx -o pcx -F %TMPDIR%\pcx.trk +%PNAME% -t -i pcx -f reference\track\pcx.trk -o pcx -F %TMPDIR%\pcx2.trk +@echo off +@echo. +CALL :COMPARE %TMPDIR%\pcx.trk %TMPDIR%\pcx2.trk +REM REM Magellan file format +REM @echo on @echo Testing... %PNAME% -i magellan -f reference\magfile -o magellan -F %TMPDIR%\magfile @@ -206,6 +239,17 @@ REM Magellan file format @echo. CALL :COMPARE %TMPDIR%\magfile reference\magfile +REM +REM Magellanx is just like, but with longer names. (which this admittedly +REM doesn't actually exercise...) +REM +@echo on +@echo Testing... +%PNAME% -i magellan -f reference\magfile -o magellanx -F %TMPDIR%\magfile2 +@echo off +@echo. +CALL :COMPARE %TMPDIR%\magfile2 reference\magfile + REM Navitrak DNA marker format @echo on @echo Testing... @@ -268,6 +312,22 @@ DEL %TMPDIR%\topo.mxf %TMPDIR%\tpg.mxf %TMPDIR%\geo.tpg @echo. CALL :COMPARE %TMPDIR%\tpg.mxf %TMPDIR%\topo.mxf +REM TPO (NG Topo!) file format +REM This is hard to test as the datum conversions create minute +REM inconsistencies in the coordinates. We have four reference files: +REM tpo-sample1.tpo, tpo-sample1.gpx, tpo-sample2.gpx, and +REM tpo-sample2.tpo. These are used to check the conversion to/from +REM TPO format. +DEL %TMPDIR%\tpo-sample1.gpx %TMPDIR%\tpo-sample2.tpo +@echo on +@echo Testing... +%PNAME% -t -i tpo -f reference\track\tpo-sample1.tpo -o gpx -F %TMPDIR%\tpo-sample1.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\tpo-sample1.gpx reference\track\tpo-sample1.gpx +REM ${PNAME} -t -i gpx -f reference/track/tpo-sample2.gpx -o tpo -F ${TMPDIR}/tpo-sample2.tpo +REM bincompare ${TMPDIR}/tpo-sample2.tpo reference/track/tpo-sample2.tpo + REM OZI (OziExplorer 1.1) file format DEL %TMPDIR%\oz.wpt %TMPDIR%\ozi.wpt @echo on @@ -523,6 +583,7 @@ DEL %TMPDIR%\magellan.rte @echo. CALL :COMPARE %TMPDIR%\magellan.rte reference\route\magellan.rte + REM REM GPX routes -- since GPX contains a date stamp, tests will always REM fail, so we use magellan as an interim format... @@ -558,7 +619,8 @@ DEL %TMPDIR%\route.mapsend %PNAME% -r -i mapsend -f reference\route\route.mapsend -o mapsend -F %TMPDIR%\route.mapsend @echo off @echo. -CALL :COMPARE %TMPDIR%\route.mapsend reference\route +CALL :BINCOMPARE %TMPDIR%\route.mapsend reference\route\route.mapsend + REM REM MAPSEND track format REM @@ -780,6 +842,13 @@ DEL %TMPDIR%\gn.pdb %TMPDIR%\1.gpx %TMPDIR%\2.gpx @echo off @echo. CALL :COMPARE %TMPDIR%\1.gpx %TMPDIR%\2.gpx +REM +@echo on +@echo Testing... +%PNAME% -i geoniche -f reference\gn-targets.pdb -o gpx -F %TMPDIR%\gn-targets.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\gn-targets.gpx reference\gn-targets.gpx REM REM saroute covers *.anr, *.rte, and *.rtd, but I only have an .anr for testing. @@ -826,7 +895,7 @@ DEL %TMPDIR%\igc*out %PNAME% -i gpx -f reference\igc1.gpx -o igc -F %TMPDIR%\igc.out @echo off @echo. -FINDSTR /V "XXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_igc.out @echo on @@ -841,7 +910,7 @@ CALL :COMPARE %TMPDIR%\igc.gpx reference\igc1_gpx.out %PNAME% -i gpx -f %TMPDIR%\igc.gpx -o igc -F %TMPDIR%\igc.out @echo off @echo. -FINDSTR /V "XXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_igc.out @echo on @@ -849,7 +918,7 @@ CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_igc.out %PNAME% -i gpx -f reference\igc1_baro.gpx -i igc -f reference\igc1_igc.out -o igc,timeadj=auto -F %TMPDIR%\igc.out @echo off @echo. -FINDSTR /V "XXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc1_3d.out @@ -865,7 +934,7 @@ CALL :COMPARE %TMPDIR%\igc.gpx reference\igc2_gpx.out %PNAME% -i gpx -f %TMPDIR%\igc.gpx -o igc -F %TMPDIR%\igc.out @echo off @echo. -FINDSTR /V "XXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out +FINDSTR /V /R /C:"^LXXXGenerated by GPSBabel Version" %TMPDIR%\igc.out> %TMPDIR%\igc_sed.out CALL :COMPARE %TMPDIR%\igc_sed.out reference\igc2_igc.out @echo on @@ -881,18 +950,26 @@ REM DEL %TMPDIR%\google.out @echo on @echo Testing... -%PNAME% -i google -f reference\google.xml -o arc -F %TMPDIR%\google.out +%PNAME% -i google -f reference\google.xml -o csv -F %TMPDIR%\google.out @echo off @echo. -CALL :COMPARE %TMPDIR%\google.out reference\google.arc +CALL :COMPARE %TMPDIR%\google.out reference\google.csv DEL %TMPDIR%\google.out @echo on @echo Testing... -%PNAME% -i google -f reference\google.js -o arc -F %TMPDIR%\google.out +%PNAME% -i google -f reference\google.js -o csv -F %TMPDIR%\google.out @echo off @echo. -CALL :COMPARE %TMPDIR%\google.out reference\google.arc +CALL :COMPARE %TMPDIR%\google.out reference\google.csv + +DEL %TMPDIR%\google.out +@echo on +@echo Testing... +%PNAME% -i google -f reference\google_jan_06.html -o csv -F %TMPDIR%\google.out +@echo off +@echo. +CALL :COMPARE %TMPDIR%\google.out reference\google_jan_06.csv REM REM DeLorme .an1 tests @@ -911,7 +988,7 @@ DEL %TMPDIR%\an1.out %PNAME% -i an1 -f reference\foo.an1 -o an1 -F %TMPDIR%\an1.out @echo off @echo. -CALL :COMPARE %TMPDIR%\an1.out reference\an1-an1.ref +CALL :BINCOMPARE %TMPDIR%\an1.out reference\an1-an1.ref DEL %TMPDIR%\an1.out @echo on @@ -919,7 +996,7 @@ DEL %TMPDIR%\an1.out %PNAME% -i xmap -f reference\xmap -o an1 -F %TMPDIR%\an1.out @echo off @echo. -CALL :COMPARE %TMPDIR%\an1.out reference\an1-out.ref +CALL :BINCOMPARE %TMPDIR%\an1.out reference\an1-out.ref DEL %TMPDIR%\an1.out @echo on @@ -927,7 +1004,7 @@ DEL %TMPDIR%\an1.out %PNAME% -i google -f reference\google.js -o an1 -F %TMPDIR%\an1.out @echo off @echo. -CALL :COMPARE %TMPDIR%\an1.out reference\an1-line-out.ref +CALL :BINCOMPARE %TMPDIR%\an1.out reference\an1-line-out.ref REM REM TomTom .ov2 tests @@ -1016,7 +1093,7 @@ REM @echo on @echo Testing... -%PNAME% -i geo -f geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o +%PNAME% -i geo -f geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o arc -F %TMPDIR%\stackfilt.txt @echo off @echo. @@ -1027,19 +1104,21 @@ REM @echo on @echo Testing... -%PNAME% -i geo -f geocaching.loc -o tabsep -F - | %PNAME% -i tabsep -f - -o geo -F %TMPDIR%\tabsep.out +%PNAME% -i geo -f geocaching.loc -o tabsep -F %TMPDIR%\tabsep.in +%PNAME% -i tabsep -f %TMPDIR%\tabsep.in -o geo -F %TMPDIR%\tabsep.out %PNAME% -i geo -f geocaching.loc -o geo -F %TMPDIR%\geotabsep.out @echo off @echo. +CALL :COMPARE %TMPDIR%\tabsep.out %TMPDIR%\geotabsep.out REM REM Now do the same for custom - it has the same issues. REM -CALL :COMPARE %TMPDIR%\tabsep.out %TMPDIR%\geotabsep.out @echo on @echo Testing... -%PNAME% -i geo -f geocaching.loc -o custom -F - | %PNAME% -i custom -f - -o geo -F %TMPDIR%\custom.out +%PNAME% -i geo -f geocaching.loc -o custom -F %TMPDIR%\custom.in +%PNAME% -i custom -f %TMPDIR%\custom.in -o geo -F %TMPDIR%\custom.out %PNAME% -i geo -f geocaching.loc -o geo -F %TMPDIR%\geocustom.out @echo off @echo. @@ -1062,7 +1141,7 @@ DEL %TMPDIR%\tef_xml* %PNAME% -r -i tef -f reference\route\tef_xml.sample.xml -o gpx -F %TMPDIR%\tef_xml.sample.gpx @echo off @echo. -CALL :COMPARE reference\route\tef_xml.sample.gpx %TMPDIR%\tef_xml.sample.gpx +CALL :COMPARE %TMPDIR%\tef_xml.sample.gpx reference\route\tef_xml.sample.gpx REM REM PathAway Palm Database .pdb tests @@ -1089,20 +1168,21 @@ REM DEL %TMPDIR%\gdb-* @echo on @echo Testing... -%PNAME% -w -r -t -i gdb -f reference\gdb-sample.gdb -o gpx -F %TMPDIR%\gdb-sample.gpx +%PNAME% -i gdb,via -f reference\gdb-sample.gdb -o gpx -F %TMPDIR%\gdb-sample.gpx @echo off @echo. CALL :COMPARE reference\gdb-sample.gpx %TMPDIR%\gdb-sample.gpx @echo on @echo Testing... -%PNAME% -w -r -t -i gpx -f reference\gdb-sample.gpx -o gdb,ver=1 -F %TMPDIR%\gdb-sample.gdb -%PNAME% -w -r -t -i gdb -f %TMPDIR%\gdb-sample.gdb -o gpx -F %TMPDIR%\gdb-sample.gpx +%PNAME% -i gpx -f reference\gdb-sample.gpx -o gdb,ver=1 -F %TMPDIR%\gdb-sample.gdb +%PNAME% -i gdb -f %TMPDIR%\gdb-sample.gdb -o gpx -F %TMPDIR%\gdb-sample.gpx @echo off @echo. REM REM Because of Garmin coordinates storage gpx is not good for this test REM compare reference/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx REM +REM compare ${TMPDIR}/gdb-sample.gpx reference/gdb-sample.gpx REM REM Vito Navigator II .smt tests @@ -1129,10 +1209,10 @@ DEL %TMPDIR%\trackfilter* @echo on @echo Testing... -%PNAME% -t -i gpx -f reference\track\trackfilter.gpx -x track,pack,split,title=LOG-%%Y%%m%%d -o gpx -F %TMPDIR%\trackfilter-new.gpx +%PNAME% -t -i gpx -f reference\track\trackfilter.gpx -x track,pack,split,title=LOG-%%Y%%m%%d -o gpx -F %TMPDIR%\trackfilter.gpx @echo off @echo. -CALL :COMPARE %TMPDIR%\trackfilter.ref %TMPDIR%\trackfilter.new +CALL :COMPARE %TMPDIR%\trackfilter.gpx reference\track\trackfilter.gpx REM REM Map&Guide Motorrad Routenplaner .bcr files test @@ -1143,7 +1223,7 @@ DEL %TMPDIR%\bcr* %PNAME% -r -i bcr -f reference\route\bcr-sample.bcr -o gpx -F %TMPDIR%\bcr-sample.gpx @echo off @echo. -CALL :COMPARE reference\route\bcr-sample.gpx %TMPDIR%\bcr-sample.gpx +CALL :COMPARE %TMPDIR%\bcr-sample.gpx reference\route\bcr-sample.gpx @echo on @echo Testing... %PNAME% -r -i gpx -f reference\route\bcr-sample.gpx -o bcr -F %TMPDIR%\bcr-sample2.bcr @@ -1155,7 +1235,41 @@ CALL :COMPARE reference\route\bcr-sample2.bcr %TMPDIR%\bcr-sample2.bcr %PNAME% -r -i bcr -f %TMPDIR%\bcr-sample2.bcr -o gpx -F %TMPDIR%\bcr-sample2.gpx @echo off @echo. -CALL :COMPARE reference\route\bcr-sample.gpx %TMPDIR%\bcr-sample2.gpx + +REM +REM cet - Character encoding transformation tests +REM +DEL %TMPDIR%\cet-sample* +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o gpx -F %TMPDIR%\cet-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.gpx reference\cet\cet-sample.gpx +@echo on +@echo Testing... +%PNAME% -w -i gpx -f %TMPDIR%\cet-sample.gpx -o tmpro -c Latin1 -F %TMPDIR%\cet-sample.latin1.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.latin1.txt reference\cet\cet-sample.latin1.txt +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o tmpro -c Latin2 -F %TMPDIR%\cet-sample.latin2.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.latin2.txt reference\cet\cet-sample.latin2.txt +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o tmpro -c cp1250 -F %TMPDIR%\cet-sample.cp1250.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.cp1250.txt reference\cet\cet-sample.cp1250.txt +@echo on +@echo Testing... +%PNAME% -w -i gdb -f reference\cet\cet-sample.gdb -o tmpro -c macroman -F %TMPDIR%\cet-sample.macroman.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cet-sample.macroman.txt reference\cet\cet-sample.macroman.txt REM REM Garmin logbook. This format has an extra section (lap data with things @@ -1177,12 +1291,14 @@ REM REM Dop filter test REM DEL %TMPDIR%\dop* +FINDSTR /V /R /C:"50" reference\dop-test.gpx | %PNAME% -i gpx -f - -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-hdop.ref @echo on @echo Testing... %PNAME% -i gpx -f reference\dop-test.gpx -x discard,hdop=50 -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-hdop.fil @echo off @echo. CALL :COMPARE %TMPDIR%\dop-hdop.ref %TMPDIR%\dop-hdop.fil +FINDSTR /V /R /C:"50" reference\dop-test.gpx | %PNAME% -i gpx -f - -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-vdop.ref @echo on @echo Testing... %PNAME% -i gpx -f reference\dop-test.gpx -x discard,vdop=50 -o openoffice -F - | sed 's\RPT...\\g'> %TMPDIR%\dop-vdop.fil @@ -1191,28 +1307,294 @@ CALL :COMPARE %TMPDIR%\dop-hdop.ref %TMPDIR%\dop-hdop.fil CALL :COMPARE %TMPDIR%\dop-vdop.ref %TMPDIR%\dop-vdop.fil REM -REM cotoGPS test +REM cotoGPS tests REM DEL %TMPDIR%\coto* REM Track reading @echo on @echo Testing... -%PNAME% -i coto -f reference\cototesttrack.pdb -o openoffice -F %TMPDIR%\cototrack.csv +%PNAME% -i coto -f reference\cototesttrack.pdb -o xcsv,style=reference\cototest.style -F %TMPDIR%\cototrack.csv @echo off @echo. CALL :COMPARE reference\cototesttrack.csv %TMPDIR%\cototrack.csv -REM Marker read/write +REM Marker read @echo on @echo Testing... -%PNAME% -i coto -f reference\cototestmarker.pdb -o openoffice -F %TMPDIR%\cotomarker.csv -%PNAME% -i gpx -f reference\cototestmarker.gpx -o openoffice -F %TMPDIR%\cotomarkergpx.csv +%PNAME% -i coto -f reference\cototestmarker.pdb -o gpx -F %TMPDIR%\cotomarker.gpx @echo off @echo. -CALL :COMPARE %TMPDIR%\cotomarker.csv %TMPDIR%\cotomarkergpx.csv +CALL :COMPARE reference\cototestmarker.gpx %TMPDIR%\cotomarker.gpx +REM Marker write @echo on @echo Testing... %PNAME% -i gpx -f reference\cototestmarker.gpx -o coto -F %TMPDIR%\cotomarker.pdb @echo off @echo. -CALL :COMPARE reference\cototestmarker.pdb %TMPDIR%\cotomarker.pdb +REM bincompare reference/cototestmarker.pdb ${TMPDIR}/cotomarker.pdb +@echo on +@echo Testing... +%PNAME% -i coto -f %TMPDIR%\cotomarker.pdb -o gpx -F %TMPDIR%\cotomarker.gpx +@echo off +@echo. +CALL :COMPARE reference\cototestmarker.gpx %TMPDIR%\cotomarker.gpx + +REM +REM Fugawi test cases +DEL %TMPDIR%\fugawi* +@echo on +@echo Testing... +%PNAME% -i fugawi -f reference\fugawi.notime.txt -o fugawi -F %TMPDIR%\fugawi1.txt +@echo off +@echo. +CALL :COMPARE reference\fugawi.ref.txt %TMPDIR%\fugawi1.txt +@echo on +@echo Testing... +%PNAME% -i geo -f geocaching.loc -o fugawi -F %TMPDIR%\fugawi2.txt +@echo off +@echo. +CALL :COMPARE reference\fugawi.ref.txt %TMPDIR%\fugawi2.txt +@echo on +@echo Testing... +%PNAME% -i fugawi -f %TMPDIR%\fugawi2.txt -o fugawi -F %TMPDIR%\fugawi3.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\fugawi2.txt %TMPDIR%\fugawi3.txt +@echo on +@echo Testing... +%PNAME% -i fugawi -f reference\fugawi.time.txt -o fugawi -F %TMPDIR%\fugawi4.txt +@echo off +@echo. +CALL :COMPARE reference\fugawi.time.ref.txt %TMPDIR%\fugawi4.txt +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\track\tracks.gpx -o fugawi -F %TMPDIR%\fugawi5.txt +@echo off +@echo. +CALL :COMPARE reference\track\fugawi.txt %TMPDIR%\fugawi5.txt + +REM +REM Magellan Explorist geocaching format (write-only). +REM +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\gc\GC7FA4.gpx -f reference\gc\GCGCA8.gpx -o maggeo -F %TMPDIR%\maggeo.gs +@echo off +@echo. +CALL :COMPARE reference\gc\maggeo.gs %TMPDIR%\maggeo.gs + +REM +REM IGN Rando tests +REM +@echo on +@echo Testing... +%PNAME% -i ignrando -f reference\track\ignrando-sample.rdn -o ignrando -F %TMPDIR%\ignrando-sample.rdn +%PNAME% -i ignrando -f %TMPDIR%\ignrando-sample.rdn -o gpx -F %TMPDIR%\ignrando-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\ignrando-sample.gpx reference\track\ignrando-sample.gpx + +REM +REM STMwpp "Suunto Trek Manager" WaypointPlus format tests +REM +DEL %TMPDIR%\stmwpp-* +@echo on +@echo Testing... +%PNAME% -i stmwpp -f reference\track\stmwpp-track.txt -o gpx -F %TMPDIR%\stmwpp-track.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\stmwpp-track.gpx reference\track\stmwpp-track.gpx +@echo on +@echo Testing... +%PNAME% -i stmwpp -f reference\route\stmwpp-route.txt -o gpx -F %TMPDIR%\stmwpp-route.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\stmwpp-route.gpx reference\route\stmwpp-route.gpx +@echo on +@echo Testing... +%PNAME% -i stmwpp -f reference\route\stmwpp-route.txt -o stmwpp -F %TMPDIR%\stmwpp-route.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\stmwpp-route.txt reference\route\stmwpp-route.txt + +REM +REM Microsoft AutoRoute 2002 test (read-only) +REM +@echo on +@echo Testing... +%PNAME% -i msroute -f reference\route\msroute-sample.axe -o gpx -F %TMPDIR%\msroute-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\msroute-sample.gpx reference\route\msroute-sample.gpx + +REM +REM CarteSurTable read test +REM +DEL %TMPDIR%\cst-* +@echo on +@echo Testing... +%PNAME% -i cst -f reference\route\cst-sample.cst -o gpx -F %TMPDIR%\cst-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\cst-sample.gpx reference\route\cst-sample.gpx + +REM +REM Navigon Mobile Navigator .rte tests +REM +DEL %TMPDIR%\nmn4-sample* +@echo on +@echo Testing... +%PNAME% -i nmn4 -f reference\route\nmn4-sample.rte -o gpx -F %TMPDIR%\nmn4-sample.gpx +@echo off +@echo. +CALL :COMPARE reference\route\nmn4-sample.gpx %TMPDIR%\nmn4-sample.gpx +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\route\nmn4-sample.gpx -o nmn4 -F %TMPDIR%\nmn4-sample-out.rte +@echo off +@echo. +CALL :COMPARE reference\route\nmn4-sample-out.rte %TMPDIR%\nmn4-sample-out.rte + +REM +REM Map&Guide Palm/OS .pdb files (read-only) +REM +DEL %TMPDIR%\mag_pdb-* +@echo on +@echo Testing... +%PNAME% -i mag_pdb -f reference\route\mag_pdb-sample.pdb -o gpx -F %TMPDIR%\mag_pdb-sample.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\mag_pdb-sample.gpx reference\route\mag_pdb-sample.gpx + +REM +REM CompeGPS I/O tests +REM +DEL %TMPDIR%\compegps* +REM read (CompeGPS) +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\compegps.wpt -o gpx -F %TMPDIR%\compegps-wpt.gpx +@echo off +@echo. +CALL :COMPARE reference\compegps-wpt.gpx %TMPDIR%\compegps-wpt.gpx +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\route\compegps.rte -o gpx -F %TMPDIR%\compegps-rte.gpx +@echo off +@echo. +CALL :COMPARE reference\route\compegps-rte.gpx %TMPDIR%\compegps-rte.gpx +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\track\compegps.trk -o gpx -F %TMPDIR%\compegps-trk.gpx +@echo off +@echo. +CALL :COMPARE reference\track\compegps-trk.gpx %TMPDIR%\compegps-trk.gpx +REM write (CompeGPS) +@echo on +@echo Testing... +%PNAME% -i compegps -f reference\compegps.wpt -o compegps -F %TMPDIR%\compegps.wpt +%PNAME% -i compegps -f %TMPDIR%\compegps.wpt -o gpx -F %TMPDIR%\compegps-wpt2.gpx +@echo off +@echo. +CALL :COMPARE reference\compegps-wpt.gpx %TMPDIR%\compegps-wpt2.gpx +@echo on +@echo Testing... +%PNAME% -t -i compegps -f reference\track\compegps.trk -o compegps -F %TMPDIR%\compegps.trk +%PNAME% -i compegps -f %TMPDIR%\compegps.trk -o gpx -F %TMPDIR%\compegps-trk2.gpx +@echo off +@echo. +CALL :COMPARE reference\track\compegps-trk.gpx %TMPDIR%\compegps-trk2.gpx +@echo on +@echo Testing... +%PNAME% -r -i compegps -f reference\route\compegps.rte -o compegps -F %TMPDIR%\compegps.rte +%PNAME% -i compegps -f %TMPDIR%\compegps.rte -o gpx -F %TMPDIR%\compegps-rte2.gpx +@echo off +@echo. +CALL :COMPARE reference\route\compegps-rte.gpx %TMPDIR%\compegps-rte2.gpx + +REM +REM Testing the 'nuketypes' filter is funky. +REM Convert a GPX file to GPX to eliminate jitter. +REM Then nuke the all but the three individual types, merge the result together +REM and verify we got the original back. +REM +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\gdb-sample.gpx -o gpx -F %TMPDIR%\alltypes.gpx +%PNAME% -i gpx -f %TMPDIR%\alltypes.gpx -x nuketypes,tracks,routes -o gpx -F %TMPDIR%\wpts.gpx +%PNAME% -i gpx -f %TMPDIR%\alltypes.gpx -x nuketypes,waypoints,routes -o gpx -F %TMPDIR%\trks.gpx +%PNAME% -i gpx -f %TMPDIR%\alltypes.gpx -x nuketypes,waypoints,tracks -o gpx -F %TMPDIR%\rtes.gpx +%PNAME% -i gpx -f %TMPDIR%\wpts.gpx -f %TMPDIR%\trks.gpx -f %TMPDIR%\rtes.gpx -o gpx -F %TMPDIR%\merged.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\alltypes.gpx %TMPDIR%\merged.gpx + +REM +REM Interpolate filter +REM + +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\track\simpletrack.gpx -x interpolate,distance=50m -o gpx -F %TMPDIR%\interp.gpx +@echo off +@echo. +CALL :COMPARE reference\track\interptrack.gpx %TMPDIR%\interp.gpx +@echo on +@echo Testing... +%PNAME% -i gpx -f reference\track\simpletrack.gpx -x interpolate,time=1 -o gpx -F %TMPDIR%\tinterp.gpx +@echo off +@echo. +CALL :COMPARE reference\track\tinterptrack.gpx %TMPDIR%\tinterp.gpx + +REM +REM Universal CSV - unicsv +REM +ECHO lat,lon,descr,name,notes,unk,unk> %TMPDIR%\unicsv.txt +TYPE reference\mxf.mxf>> %TMPDIR%\unicsv.txt +@echo on +@echo Testing... +%PNAME% -i unicsv -f %TMPDIR%\unicsv.txt -o gpx -F %TMPDIR%\unicsv.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\unicsv.gpx reference\unicsv.gpx + +REM +REM Basic NMEA tests +REM +@echo on +@echo Testing... +%PNAME% -i nmea -f reference\track\nmea -o gpx -F %TMPDIR%\nmea.gpx +@echo off +@echo. +CALL :COMPARE %TMPDIR%\nmea.gpx reference\track\nmea.gpx + +REM +REM Wfff. +REM +@echo on +@echo Testing... +%PNAME% -i wfff -f reference\wfff.xml -o gpsutil -F %TMPDIR%\wfff.gpu +@echo off +@echo. +CALL :COMPARE %TMPDIR%\wfff.gpu reference\wfff.gpu + +REM +REM Garmin MapSource tab delimited text files - garmin_txt +REM +DEL %TMPDIR%\garmin_txt* +REM +REM !!! garmin_txt timestamps are stored in localtime !!! +REM +@echo on +@echo Testing... +%PNAME% -i gdb -f reference\gdb-sample2.gdb -o garmin_txt,utc,prec=9 -F %TMPDIR%\garmin_txt.txt +@echo off +@echo. +CALL :COMPARE reference\garmin_txt.txt %TMPDIR%\garmin_txt.txt +@echo on +@echo Testing... +%PNAME% -i garmin_txt -f reference\garmin_txt.txt -o garmin_txt,prec=9 -F %TMPDIR%\garmin_txt-2.txt +%PNAME% -i garmin_txt -f %TMPDIR%\garmin_txt-2.txt -o garmin_txt,prec=9 -F %TMPDIR%\garmin_txt-3.txt +@echo off +@echo. +CALL :COMPARE %TMPDIR%\garmin_txt-2.txt %TMPDIR%\garmin_txt-3.txt diff --git a/mkicondoc.c b/mkicondoc.c new file mode 100644 index 000000000..ac4d30b8f --- /dev/null +++ b/mkicondoc.c @@ -0,0 +1,67 @@ +#include +#include +#include "fatal.c" +#include "util.c" +#include "cet.c" +#define VERSION "1" +#include "globals.c" + + + +tbl_ent(int n, ...) +{ + int i; + char *t; + va_list args; + va_start(args, n); +#if 0 + for (i = 0; i < n; i++) { + t = va_arg(args, char *); +printf("%s%s", i > 0 ? "," : "", t); + + } +#else + t = va_arg(args, char*); + printf("%s", t); +#endif +printf("\n"); + va_end(args); + + +} + +#include "garmin_tables.c" +sort_garmin(const void *a, const void *b) +{ + const icon_mapping_t *ap = a; + const icon_mapping_t *bp = b; + return (case_ignore_strcmp((ap)->icon, (bp)->icon)); +} + +garmin() +{ + icon_mapping_t *i; + int n = 0; + char pbuf[100]; + char mbuf[100]; + + for (i = garmin_icon_table; i->icon; i++) { + n++; + } + + qsort(garmin_icon_table, + n, + sizeof(garmin_icon_table[0]), + sort_garmin); + + for (i = garmin_icon_table; i->icon; i++) { + snprintf(pbuf, sizeof(pbuf), "%d", i->pcxsymnum); + snprintf(mbuf, sizeof(mbuf), "%d", i->mpssymnum); + tbl_ent(3, i->icon, pbuf, mbuf); + } +} + +main() +{ + garmin(); +} diff --git a/mkshort.c b/mkshort.c index b670d31d9..daa751434 100644 --- a/mkshort.c +++ b/mkshort.c @@ -1,7 +1,7 @@ /* Generate unique short names. - Copyright (C) 2003, 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ static const char vowels[] = "aeiouAEIOU"; #define DEFAULT_TARGET_LEN 8 -#define DEFAULT_BADCHARS "\"$.,'!-" +static const char *DEFAULT_BADCHARS = "\"$.,'!-"; /* * Hash table tunings. The reality is that our hash doesn't have to be @@ -39,14 +39,17 @@ static const char vowels[] = "aeiouAEIOU"; #define PRIME 37 typedef struct { - int mustupper; - int whitespaceok; unsigned int target_len; char *badchars; char *goodchars; - int must_uniq; + char *defname; queue namelist[PRIME]; - int depth[PRIME]; + + /* Various internal flags at end to allow alignment flexibility. */ + unsigned int mustupper:1; + unsigned int whitespaceok:1; + unsigned int repeating_whitespaceok:1; + unsigned int must_uniq:1; } mkshort_handle; typedef struct { @@ -55,6 +58,23 @@ typedef struct { int conflictctr; } uniq_shortname; +static struct replacements { + const char *orig; + const char *replacement; +} replacements[] = { + {"zero", "0"}, + {"one", "1"}, + {"two", "2"}, + {"three", "3"}, + {"four", "4"}, + {"five", "5"}, + {"six", "6"}, + {"seven", "7"}, + {"eight", "8"}, + {"nine", "9"}, + {NULL, NULL} +}; + /* * We hash all strings as upper case. */ @@ -82,9 +102,10 @@ mkshort_new_handle() QUEUE_INIT(&h->namelist[i]); h->whitespaceok = 1; - h->badchars = DEFAULT_BADCHARS; + h->badchars = xstrdup(DEFAULT_BADCHARS); h->target_len = DEFAULT_TARGET_LEN; - h->must_uniq=1; + h->must_uniq = 1; + h->defname = xstrdup("WPT"); return h; } @@ -145,12 +166,12 @@ mkshort_add_to_list(mkshort_handle *h, char *name) } void -mkshort_del_handle(void *h) +mkshort_del_handle(short_handle *h) { - mkshort_handle *hdr = h; + mkshort_handle *hdr = (mkshort_handle*) *h; int i; - if (!hdr) + if (!h || !hdr) return; for (i = 0; i < PRIME; i++) { @@ -168,7 +189,17 @@ mkshort_del_handle(void *h) xfree(s); } } + /* setshort_badchars(*h, NULL); ! currently setshort_badchars() always allocates something ! */ + if (hdr->badchars != NULL) { + xfree(hdr->badchars); + } + setshort_goodchars(*h, NULL); + if (hdr->defname) { + xfree(hdr->defname); + } + xfree(hdr); + *h = NULL; } /* @@ -200,17 +231,42 @@ delete_last_vowel(int start, char *istring, int *replaced) } } return istring; +} +/* + * Open the slippery slope of literal replacement. Right now, replacements + * are made only at the end of the string. + */ +void +replace_constants(char *s) +{ + struct replacements *r; + int origslen = strlen(s); + + for (r = replacements; r->orig; r++) { + int rl = strlen(r->orig); + /* + * If word is in replacement list and preceeded by a + * space, replace it. + */ + if ((origslen - rl > 1) && + (0 == case_ignore_strcmp(r->orig, &s[origslen - rl])) && + (s[origslen - rl - 1] == ' ')) { + strcpy(&s[origslen - rl], r->replacement); + return ; } + } +} + /* * Externally callable function to set the max length of the * strings returned by mkshort(). 0 resets to default. */ void -setshort_length(void *h, int l) +setshort_length(short_handle h, int l) { - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; if (l == 0) { hdl->target_len = DEFAULT_TARGET_LEN; } else { @@ -218,55 +274,104 @@ setshort_length(void *h, int l) } } +/* + * Call with L nonzero if whitespace in the generated shortname is wanted. + */ + void -setshort_whitespace_ok(void *h, int l) +setshort_whitespace_ok(short_handle h, int l) { - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; hdl->whitespaceok = l; } /* - * Externally callable function to set the string of characters - * that must never appear in a string returned by mkshort. NULL - * resets to default. + * Call with L nonzero if multiple consecutive whitespace in the + * generated shortname is wanted. */ + void -setshort_badchars(void *h, const char *s) +setshort_repeating_whitespace_ok(short_handle h, int l) { - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->repeating_whitespaceok = l; +} + +/* + * Set default name given to a waypoint if no valid is possible + * becuase it was filtered by charsets or null or whatever. + */ +void +setshort_defname(short_handle h, const char *s) +{ + mkshort_handle *hdl = (mkshort_handle *) h; if (s == NULL) { - hdl->badchars = DEFAULT_BADCHARS; - } else { - hdl->badchars = xstrdup(s); + fatal("setshort_defname called without a valid name."); } + if (hdl->defname != NULL) + xfree(hdl->defname); + hdl->defname = xstrdup(s); } + +/* + * Externally callable function to set the string of characters + * that must never appear in a string returned by mkshort. NULL + * resets to default. + */ void -setshort_goodchars(void *h, const char *s) +setshort_badchars(short_handle h, const char *s) { - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; - hdl->goodchars = xstrdup(s); + if ((hdl->badchars != NULL)) + xfree(hdl->badchars); + hdl->badchars = xstrdup (s ? s : DEFAULT_BADCHARS); } +/* + * Only characters that appear in *s are "whitelisted" to appear + * in generated names. + */ +void +setshort_goodchars(short_handle h, const char *s) +{ + mkshort_handle *hdl = (mkshort_handle *) h; + + if (hdl->goodchars != NULL) + xfree(hdl->goodchars); + if (s != NULL) + hdl->goodchars = xstrdup(s); + else + hdl->goodchars = NULL; +} + +/* + * Call with i non-zero if generated names must be uppercase only. + */ void -setshort_mustupper(void *h, int i) +setshort_mustupper(short_handle h, int i) { - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; hdl->mustupper = i; } + +/* + * Call with i zero if the generated names don't have to be unique. + * (By default, they are.) + */ void -setshort_mustuniq(void *h, int i) +setshort_mustuniq(short_handle h, int i) { - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; hdl->must_uniq = i; } char * #ifdef DEBUG_MEM -MKSHORT(void *h, const char *istring, DEBUG_PARAMS ) +MKSHORT(short_handle h, const char *istring, DEBUG_PARAMS ) #else -mkshort(void *h, const char *istring) +mkshort(short_handle h, const char *istring) #endif { char *ostring = xxstrdup(istring, file, line); @@ -275,7 +380,7 @@ mkshort(void *h, const char *istring) char *cp; char *np; int i, l, nlen, replaced; - mkshort_handle *hdl = h; + mkshort_handle *hdl = (mkshort_handle *) h; /* * Whack leading "[Tt]he", @@ -318,15 +423,21 @@ mkshort(void *h, const char *istring) *tstring = toupper(*tstring); } } + + /* Before we do any of the vowel or character removal, look for + * constants to replace. + */ + + replace_constants(ostring); + /* * Eliminate chars on the blacklist. - * Characters that aren't ASCII are never OK. */ tstring = xxstrdup(ostring, file, line); l = strlen (tstring); cp = ostring; for (i=0;ibadchars, tstring[i]) || !isascii(tstring[i])) + if (strchr(hdl->badchars, tstring[i])) continue; if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i]))) continue; @@ -339,9 +450,11 @@ mkshort(void *h, const char *istring) * Eliminate repeated whitespace. This can only shorten the string * so we do it in place. */ - for (i = 0; i < l-1; i++) { - if (ostring[i] == ' ' && ostring[i+1] == ' ') { - memmove(&ostring[i], &ostring[i+1], l-i); + if (!hdl->repeating_whitespaceok) { + for (i = 0; i < l-1; i++) { + if (ostring[i] == ' ' && ostring[i+1] == ' ') { + memmove(&ostring[i], &ostring[i+1], l-i); + } } } @@ -359,8 +472,19 @@ mkshort(void *h, const char *istring) /* * Delete vowels starting from the end. If it fits, quit stomping * them. If we run out of string, give up. + * + * Skip this test is our target length is arbitrarily considered + * "long" as it turns out a truncated string of full words is easier + * to read than a full string of vowelless words. + * + * It also helps units with speech synthesis. */ - replaced = 1; + if ( hdl->target_len < 15) { + replaced = 1; + } else { + replaced = 0; + } + while (replaced && strlen(ostring) > hdl->target_len) { ostring = delete_last_vowel(2, ostring, &replaced); } @@ -371,8 +495,9 @@ mkshort(void *h, const char *istring) * Walk in the Woods 1. * Walk in the Woods 2. */ + np = ostring + strlen(ostring); - while (*(np-1) && isdigit(*(np-1) )) { + while ((np != ostring) && *(np-1) && isdigit(*(np-1) )) { np--; } if (np) { @@ -382,9 +507,14 @@ mkshort(void *h, const char *istring) /* * Now brutally truncate the resulting string, preserve trailing * numeric data. + * If the numeric component alone is longer than our target string + * length, use only what'll fit. */ if ((/*i = */strlen(ostring)) > hdl->target_len) { - strcpy(&ostring[hdl->target_len] - strlen(np), np); + char *dp = &ostring[hdl->target_len] - strlen(np); + if (dp < ostring) dp = ostring; + memmove(dp, np, strlen(np)); + dp[strlen(np)] = 0; } /* @@ -393,7 +523,7 @@ mkshort(void *h, const char *istring) */ if (ostring[0] == '\0') { xfree(ostring); - ostring = xstrdup("WPT"); + ostring = xstrdup(hdl->defname); } if (hdl->must_uniq) { @@ -407,14 +537,15 @@ mkshort(void *h, const char *istring) * the code that considers the alternate sources. */ char * -mkshort_from_wpt(void *h, const waypoint *wpt) +mkshort_from_wpt(short_handle h, const waypoint *wpt) { /* This probably came from a Groundspeak Pocket Query * so use the 'cache name' instead of the description field * which contains placer name, diff, terr, and generally way * more stuff than should be in any one field... */ - if (wpt->gc_data.diff && wpt->gc_data.terr && wpt->notes) { + if (wpt->gc_data.diff && wpt->gc_data.terr && + wpt->notes && wpt->notes[0]) { return mkshort(h, wpt->notes); } diff --git a/mkstyle.sh b/mkstyle.sh index 418e60f05..19db383a3 100644 --- a/mkstyle.sh +++ b/mkstyle.sh @@ -3,6 +3,8 @@ echo "/* This file is machine-generated from the contents of style/ */" echo "/* by mkstyle.sh. Editing it by hand is an exeedingly bad idea. */" echo +echo "#include \"defs.h\"" +echo "#if CSVFMTS_ENABLED" nstyles="0" for i in style/*.style do @@ -15,7 +17,10 @@ do echo ";" nstyles=`expr $nstyles + 1`; done - -echo "#include \"defs.h\"" echo "style_vecs_t style_list[] = {$ALIST {0,0}};" echo "size_t nstyles = $nstyles;" +echo "#else /* CSVFMTS_ENABLED */" +echo "style_vecs_t style_list[] = {{0,0}};" +echo "size_t nstyles = 0;" +echo "#endif /* CSVFMTS_ENABLED */" + diff --git a/msroute.c b/msroute.c new file mode 100644 index 000000000..3d90b917d --- /dev/null +++ b/msroute.c @@ -0,0 +1,675 @@ +/* + + Support for Microsoft AutoRoute 2002 ".axe" files, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +*/ + +#include "defs.h" +#include "jeeps/gpsmath.h" +#include + +#define MYNAME "msroute" + +#undef OLE_DEBUG + +static FILE *fin; +static char *fin_name; + +static arglist_t msroute_args[] = +{ + ARG_TERMINATOR +}; + +/* MS-AutoRoute structures */ + +typedef struct msroute_head_s +{ + gbuint32 U1; /* 58/02/00/00 */ + char masm[4]; /* "MASM " */ + gbuint32 U2; + gbuint32 U3; + gbint32 waypts; + gbuint32 U5; + gbuint32 U6; + gbuint32 U7; + gbuint32 U8; + gbuint32 U9; + gbuint32 U10; + gbuint32 U11; + gbuint32 U12; + gbuint32 U13; + gbuint32 U14; + gbuint32 U15; + gbuint32 U16; +// short U17; +// char U18; +} msroute_head_t; + +#define MSROUTE_OBJ_NAME "Journey" + +/* simple ole file reader */ + +#define OLE_MAX_NAME_LENGTH 32 +#define OLE_HEAD_FAT1_CT (512-0x4c)/4 + +#define BLOCKS(a, b) (((a) + (b) - 1) / (b)) + +static const unsigned char ole_magic[8] = +{ + 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 +}; + +/* + The ole implementation looks like a FAT filesystem. + Thatswhy i use in code fat1 as item for the "big blocks" or bbd + and fat2 for "small blocks" (sbd). + + Remarks: + + * in the moment ole_size1 and sector_size represents the same value + * in OLE_DEBUG mode: successfully tested with 64MB++ standard MS doc's (PowerPoint, Word) +*/ + +typedef struct ole_head_s +{ + char magic[8]; + char clsid[16]; + gbuint16 rev; /* offset 0x18 */ + gbuint16 ver; /* offset 0x1a */ + gbint16 byte_order; /* offset 0x1c */ + gbuint16 fat1_size_shift; /* offset 0x1e */ + gbuint16 fat2_size_shift; /* offset 0x20 */ + gbuint16 U7; /* offset 0x22 */ + gbuint32 U8; /* offset 0x24 */ + gbuint32 U9; /* offset 0x28 */ + gbint32 fat1_blocks; /* offset 0x2c */ + gbint32 prop_start; /* offset 0x30 */ + gbuint32 U12; /* offset 0x34 */ + gbuint32 fat1_min_size; /* offset 0x38 */ + gbint32 fat2_start; /* offset 0x3c */ + gbint32 fat2_blocks; /* offset 0x40 */ + gbint32 fat1_extra_start; /* offset 0x44 */ + gbint32 fat1_extra_ct; /* offset 0x48 */ + gbint32 fat1[OLE_HEAD_FAT1_CT]; /* offset 0x4c */ +} ole_head_t; + +typedef struct ole_prop_s +{ + gbuint16 name[32]; + gbuint16 name_size; /* offset 0x40 */ + char ole_typ; /* offset 0x42 */ + char U1; /* offset 0x43 */ + gbuint32 previous; /* offset 0x44 */ + gbuint32 next; /* offset 0x48 */ + gbuint32 dir; /* offset 0x4c */ + gbuint32 U5; /* offset 0x50 */ + gbuint32 U6; /* offset 0x54 */ + gbuint32 U7; /* offset 0x58 */ + gbuint32 U8; /* offset 0x5c */ + gbuint32 U9; /* offset 0x60 */ + gbuint32 U10; /* offset 0x64 */ + gbuint32 U11; /* offset 0x68 */ + gbuint32 U12; /* offset 0x6c */ + gbuint32 U13; /* offset 0x70 */ + gbint32 first_sector; /* offset 0x74 */ + gbint32 length; /* offset 0x78 */ + gbuint32 U16; /* offset 0x7c */ +} ole_prop_t; + +#define DIR_ITEM_SIZE sizeof(ole_prop_t) + +static int sector_size = 512; + +#ifndef min +#define min(a,b) ((a) < (b)) ? (a) : (b) +#endif +#ifndef max +#define max(a,b) ((a) > (b)) ? (a) : (b) +#endif + +static gbint32 *ole_fat1 = NULL; +static gbint32 *ole_fat2 = NULL; +static int ole_fat1_ct; +static int ole_fat2_ct; +static int ole_size1; +static int ole_size2; +static int ole_size1_min = 4096; +static ole_prop_t *ole_dir = NULL; +static int ole_dir_ct; +static ole_prop_t *ole_root = NULL; +static char **ole_root_sec = NULL; +static int ole_root_sec_ct; + +/* local helpers */ + +static void +le_read32_buff(int *buff, const int count) +{ + int i; + for (i = 0; i < count; i++) + buff[i] = le_read32(&buff[i]); +} + +/* simple OLE file reader */ + +static void +ole_read_sector(const int sector, void *target) +{ + int res; + + res = fseek(fin, (sector + 1) * sector_size, SEEK_SET); + is_fatal((res != 0), MYNAME ": Could not seek file to sector %d!", sector + 1); + res = fread(target, 1, sector_size, fin); + is_fatal((res < sector_size), MYNAME ": Read error (%d, sector %d) on file \"%s\"!", res, sector, fin_name); +} + +static ole_prop_t * +ole_find_property(const char *property) +{ + int i; + + for (i = 0; i < ole_dir_ct; i++) + { + int j, len; + char buff[OLE_MAX_NAME_LENGTH + 1]; + ole_prop_t *item; + + item = &ole_dir[i]; + len = min(OLE_MAX_NAME_LENGTH, item->name_size / 2); + + for (j = 0; j < len; j++) + buff[j] = le_read16(&item->name[j]); + buff[j] = '\0'; + + if (case_ignore_strcmp(buff, property) == 0) + return item; + } + is_fatal((1), MYNAME ": \"%s\" not in property catalog!", property); + return 0; +} + +static char * +ole_read_stream(const ole_prop_t *property) +{ + const char *action = "ole_read_stream"; + int len, sector, big, blocksize, offs, left; + int i; + int *fat; + char *buff; + + len = property->length; + + if (len >= ole_size1_min) + { + big = 1; + blocksize = ole_size1; + fat = ole_fat1; + } + else + { + big = 0; + blocksize = ole_size2; + fat = ole_fat2; + } + + offs = 0; + left = len; + sector = property->first_sector; + + i = ((len + blocksize - 1) / blocksize) * blocksize; + buff = xmalloc(i); /* blocksize aligned */ + + if (big != 0) + { + while (left > 0) + { + int bytes = (left <= blocksize) ? left : blocksize; + ole_read_sector(sector, buff + offs); + left -= bytes; + offs += bytes; + if (left > 0) + { + sector = fat[sector]; + is_fatal((sector < 0), MYNAME ": Broken stream (%s)!", action); + } + } + } + else + { + int chain = sector; + int blocks = (len + blocksize - 1) / blocksize; + int blocks_per_sector = sector_size / blocksize; + + offs = 0; + + while (blocks-- > 0) + { + char *temp; + int block_offs; + + is_fatal((chain < 0), MYNAME ": Broken stream (%s)!", action); + + sector = chain / blocks_per_sector; + is_fatal((sector >= ole_root_sec_ct), MYNAME ": Broken stream (%s)!", action); + + temp = ole_root_sec[sector]; + is_fatal((temp == NULL), MYNAME ": Broken stream (%s)!", action); + + block_offs = (chain % blocks_per_sector) * blocksize; + + memcpy(buff + offs, temp + block_offs, blocksize); + + offs += blocksize; + chain = fat[chain]; + } + } + return buff; +} + + +static char * +ole_read_property_stream(const char *property_name, int *length) +{ + ole_prop_t *property; + char *result; + + if ((property = ole_find_property(property_name)) == NULL) return NULL; + + result = ole_read_stream(property); + if ((result != NULL) && (length != NULL)) + *length = property->length; + + return result; +} + +#ifdef OLE_DEBUG + +static void +ole_test_properties() +{ + int i; + + for (i = 0; i < ole_dir_ct; i++) + { + char *temp; + char name[OLE_MAX_NAME_LENGTH + 1]; + ole_prop_t *p = &ole_dir[i]; + + if ((p->ole_typ != 1) && (p->ole_typ != 2) && (p->ole_typ != 5)) continue; + if ((p->length <= 0) || (p->name_size <= 0)) continue; + + temp = cet_str_uni_to_utf8(&p->name, min(p->name_size / 2, OLE_MAX_NAME_LENGTH)); + strncpy(name, temp, sizeof(name)); + xfree(temp); + + printf(MYNAME ": ole_test_properties for \"%s\" (%d bytes):", name, p->length); + + if ((case_ignore_strcmp(name, "Root Entry") == 0) || + (p->length < ole_size1_min)) + { + printf(" skipped...\n"); + continue; + } + else + { + int sector = p->first_sector; + int length = p->length; + int block_size = ole_size1; /* sector_size */ + + printf("\n"); + + while ((length > 0) && (sector >= 0)) + { + int bytes = (length > block_size) ? block_size : length; + int prev = sector; + + length -= bytes; + sector = ole_fat1[sector]; + if (sector == -3) + { + printf(MYNAME ": special block at %d\n", prev); + if ((prev + 2) < ole_fat1_ct) + sector = ole_fat1[prev + 1]; + printf(MYNAME "-new sector: %d\n", sector); + } + } + is_fatal((length != 0), MYNAME ": Error in fat1 chain, sector = %d, %d bytes (=%d blocks) left!", + sector, length, BLOCKS(length, block_size)); + } + } +} +#endif + +static void +ole_init(void) +{ + ole_head_t head; + int i, i_offs, sector, count, left; + int fat1_extra[128]; + + ole_fat1 = NULL; + ole_fat2 = NULL; + + sector_size = 512; /* fixed for the moment */ + + is_fatal((sizeof(head) != sector_size), + MYNAME ": (!) internal error - invalid header size (%lu)!", + (unsigned long) sizeof(head)); + + memset(&head, 0, sizeof(head)); + fread(&head, sizeof(head), 1, fin); + + is_fatal((strncmp(head.magic, (char *) ole_magic, sizeof(ole_magic)) != 0), MYNAME ": No MS document."); + + head.rev = le_read16(&head.rev); + head.ver = le_read16(&head.ver); + head.byte_order = le_read16(&head.byte_order); + head.fat1_size_shift = le_read16(&head.fat1_size_shift); + head.fat2_size_shift = le_read16(&head.fat2_size_shift); + head.fat1_blocks = le_read32(&head.fat1_blocks); + head.prop_start = le_read32(&head.prop_start); + head.fat1_min_size = le_read32(&head.fat1_min_size); + head.fat2_start = le_read32(&head.fat2_start); + head.fat2_blocks = le_read32(&head.fat2_blocks); + head.fat1_extra_start = le_read32(&head.fat1_extra_start); + head.fat1_extra_ct = le_read32(&head.fat1_extra_ct); + le_read32_buff(&head.fat1[0], OLE_HEAD_FAT1_CT); + + ole_size1 = (1 << head.fat1_size_shift); + ole_size2 = (1 << head.fat2_size_shift); + ole_size1_min = head.fat1_min_size; + +#ifdef OLE_DEBUG + printf(MYNAME "-head: (version.revision) = %d.%d\n", head.ver, head.rev); + printf(MYNAME "-head: byte-order = %d\n", head.byte_order); + printf(MYNAME "-head: big fat start sector = %d (0x%x)\n", head.fat1[0], (head.fat1[0] + 1) * 512); + printf(MYNAME "-head: big fat blocks = %d\n", head.fat1_blocks); + printf(MYNAME "-head: big fat block size = %d\n", (1 << head.fat1_size_shift)); + printf(MYNAME "-head: small fat start sector = %d\n", head.fat2_start); + printf(MYNAME "-head: small fat blocks = %d\n", head.fat2_blocks); + printf(MYNAME "-head: small fat block size = %d\n", (1 << head.fat2_size_shift)); + printf(MYNAME "-head: big fat minimum length = %d\n", head.fat1_min_size); + printf(MYNAME "-head: property catalog start sector = %d\n", head.prop_start); + printf(MYNAME "-head: additional big fat blocks = %d\n", head.fat1_extra_ct); + printf(MYNAME "-head: additional big fat start sector = %d (0x%x)\n", head.fat1_extra_start, (head.fat1_extra_start + 1) * 512); +#endif + + is_fatal((head.byte_order != -2), MYNAME ": Unsupported byte-order %d", head.byte_order); +#if 0 + sector_size = ole_size1; /* i'll implement this, if i get an MS-doc (ole) */ + /* with "sector_size" other than 512 */ +#else + is_fatal((ole_size1 != 512), MYNAME ": Unsupported sector size %d", ole_size1); +#endif + ole_fat1 = xmalloc(head.fat1_blocks * sector_size); + ole_fat1_ct = (head.fat1_blocks * sector_size) / sizeof(gbint32); + +#ifdef OLE_DEBUG + printf(MYNAME "-big fat: %d maximum sectors, size in memory %d, max. datasize %d bytes\n", + ole_fat1_ct, head.fat1_blocks * sector_size, head.fat1_blocks * sector_size * sector_size / sizeof(gbint32)); +#endif + + i_offs = 0; /* load "big fat" into memory */ + left = head.fat1_blocks; + count = (left > OLE_HEAD_FAT1_CT) ? OLE_HEAD_FAT1_CT : left; + + for (i = 0; i < count; i++) + { + sector = head.fat1[i]; + ole_read_sector(sector, &ole_fat1[i_offs]); + i_offs += ole_size1 / 4; + } + + left -= count; + + if (left > 0) + { + sector = head.fat1_extra_start; + + while ((left > 0) && (sector >= 0)) + { + ole_read_sector(sector, &fat1_extra); + le_read32_buff(&fat1_extra[0], 128); + + count = (left < 127) ? left : 127; + for (i = 0; i < count; i++) + { + ole_read_sector(fat1_extra[i], &ole_fat1[i_offs]); + i_offs += ole_size1 / 4; + } + left -= count; + if (left > 0) + sector = fat1_extra[127]; + } + is_fatal((left > 0), MYNAME ": Broken stream!"); + } + if (ole_fat1_ct > 0) + le_read32_buff(&ole_fat1[0], ole_fat1_ct); + + + /* load fat2 "small fat" into memory */ + + sector = head.fat2_start; + if (sector >= 0) + { + count = 0; + do + { + if (ole_fat2 == NULL) + ole_fat2 = (int *)xmalloc((count + 1) * sector_size); + else + ole_fat2 = (int *)xrealloc(ole_fat2, (count + 1) * sector_size); + + ole_read_sector(sector, (char *)ole_fat2 + (count * sector_size)); + sector = ole_fat1[sector]; + + count++; + } + while (sector >= 0); + + ole_fat2_ct = (count * sector_size) / sizeof(gbint32); + if (ole_fat2_ct > 0) + le_read32_buff(&ole_fat2[0], ole_fat2_ct); + } + + /* load directory (property catalog) */ + + sector = head.prop_start; + is_fatal((sector < 0), MYNAME ": Invalid file (no property catalog)!"); + + count = 0; + while (sector >= 0) + { + if (ole_dir == NULL) + ole_dir = (void *)xmalloc((count + 1) * sector_size); + else + ole_dir = (void *)xrealloc(ole_dir, (count + 1) * sector_size); + + ole_read_sector(sector, (char *)ole_dir + (count * sector_size)); + sector = ole_fat1[sector]; + + count++; + } + ole_dir_ct = (count * sector_size) / sizeof(ole_prop_t); + + /* fix endianess of property catalog */ + + for (i = 0; i < ole_dir_ct; i++) + { + ole_prop_t *item = &ole_dir[i]; + + item->first_sector = le_read32(&item->first_sector); + item->length = le_read32(&item->length); + } + + ole_root = ole_find_property("Root Entry"); + + /* read fat2 data sectors given by "Root Entry" */ + + ole_root_sec_ct = (ole_root->length + (sector_size - 1)) / sector_size; + ole_root_sec = xcalloc(ole_root_sec_ct + 1, sizeof(char *)); + + i = 0; + sector = ole_root->first_sector; + while (sector >= 0) + { + char *temp; + + temp = ole_root_sec[i++] = xmalloc(sector_size); + + ole_read_sector(sector, temp); + sector = ole_fat1[sector]; + } +#ifdef OLE_DEBUG + ole_test_properties(); +#endif +} + +static void +ole_deinit(void) +{ + if (ole_root_sec != NULL) + { + int i; + for (i = 0; i < ole_root_sec_ct; i++) + { + char *c; + if ((c = ole_root_sec[i])) xfree(c); + } + xfree(ole_root_sec); + } + if (ole_fat1 != NULL) xfree(ole_fat1); + if (ole_fat2 != NULL) xfree(ole_fat2); + if (ole_dir != NULL) xfree(ole_dir); +} + +/* global MS AutoRoute functions */ + +static void +msroute_read_journey(void) +{ + int len; + char *buff; + + buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &len); + + if ((buff != NULL) && (len > 0)) + { + msroute_head_t *head = (msroute_head_t *)buff; + char *cin; + int len; + char text[256]; + int count = 0; + route_head *route; + waypoint *wpt; + + is_fatal((strncmp(head->masm, "MASM", 4) != 0), MYNAME ": Invalid or unknown data!"); + + cin = buff + 71; // sizeof(msroute_head_t); + + route = route_head_alloc(); + route_add_head(route); + + head->waypts = le_read32(&head->waypts); + + while (count < head->waypts) + { + double lat, lon; + short test; + + cin++; + + len = *cin++; + strncpy(text, cin, len); + text[len] = '\0'; + + cin += len + 1; + test = le_read16(cin); + is_fatal((test != -2), MYNAME ": Unsupported byte order within data (%d).", test); + + cin += 2; + + len = *cin; /* skip wide-string 'name' */ + cin += (len * 2) + 1; + + cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ + + /* offs 12 !!!! Latitude int32 LE */ + /* offs 16 !!!! Longitude int32 LE */ + + lat = GPS_Math_Semi_To_Deg(le_read32(cin+12)); + lon = GPS_Math_Semi_To_Deg(le_read32(cin+16)); + + cin += (23 * sizeof(gbint32)); + cin += 3; + + count++; + + wpt = waypt_new(); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->shortname = xstrdup(text); +#ifdef OLE_DEBUG + waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ +#endif + route_add_wpt(route, wpt); + } + } + + if (buff != NULL) + xfree(buff); +} + +/* registered callbacks */ + +static void msroute_rd_init(const char *fname) +{ + fin_name = xstrdup(fname); + fin = xfopen(fname, "rb", MYNAME); + + ole_init(); +} + +static void msroute_rd_deinit(void) +{ + ole_deinit(); + + xfree(fin_name); + fclose(fin); +} + +static void msroute_read(void) +{ + msroute_read_journey(); +} + +ff_vecs_t msroute_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read }, + msroute_rd_init, + NULL, + msroute_rd_deinit, + NULL, + msroute_read, + NULL, + NULL, + msroute_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ +}; diff --git a/msvc/Debug.empty b/msvc/Debug.empty new file mode 100644 index 000000000..e69de29bb diff --git a/msvc/Expatw/expat.h b/msvc/Expatw/expat.h new file mode 100644 index 000000000..c6a4b3b6c --- /dev/null +++ b/msvc/Expatw/expat.h @@ -0,0 +1,1013 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + /* Added in 1.95.7. */ + XML_ERROR_UNBOUND_PREFIX, + /* Added in 1.95.8. */ + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE, + /* Added in 2.0. */ + XML_ERROR_RESERVED_PREFIX_XML, + XML_ERROR_RESERVED_PREFIX_XMLNS, + XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(*malloc_fcn)(size_t size); + void *(*realloc_fcn)(void *ptr, size_t size); + void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + It is a programming error to use the separator '\0' with namespace + triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: For the purpose of checking WFC: Entity Declared, passing + useDTD == XML_TRUE will make the parser behave as if the document + had a DTD with an external subset. + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR, + XML_FEATURE_NS + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 0 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/msvc/Expatw/expat_external.h b/msvc/Expatw/expat_external.h new file mode 100644 index 000000000..4cd16923c --- /dev/null +++ b/msvc/Expatw/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index; +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/msvc/Expatw/libexpatw.dll b/msvc/Expatw/libexpatw.dll new file mode 100644 index 0000000000000000000000000000000000000000..9aaa5a826f4bafaeef0061096e140710d5374a63 GIT binary patch literal 151552 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 lt%yz?R*WNJ{E14`M|t5!Ky - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/msvc/README.msvc b/msvc/README.msvc index 373e22a77..109648d1b 100644 --- a/msvc/README.msvc +++ b/msvc/README.msvc @@ -10,6 +10,11 @@ load the workspace and hit "build all.") If you load these files in to Visual Studio .NET, you may be asked to convert them to the new format; In that case, you should do so. +Note that the "Microsoft Platform SDK" is required in addition to +the actual compiler package. If you're using the Express editions, +you must also reconfigure MSVC to use that as described at: + http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/ + The "Expat" directory contains the import library and header file for the Expat DLL. This may or may not be the latest build of Expat; you might want to check http://expat.sourceforge.net to see if there is a more recent diff --git a/msvc/Unicode.empty b/msvc/Unicode.empty new file mode 100644 index 000000000..e69de29bb diff --git a/msvc/build.bat b/msvc/build.bat new file mode 100644 index 000000000..26c752aa6 --- /dev/null +++ b/msvc/build.bat @@ -0,0 +1,9 @@ +setlocal +set include=%include%;expat;..\coldsync;c:\tools\c +set SOURCEJEEPS=..\jeeps\gpsapp.c ..\jeeps\gpscom.c ..\jeeps\gpsmath.c ..\jeeps\gpsmem.c ..\jeeps\gpsprot.c ..\jeeps\gpsread.c ..\jeeps\gpsrqst.c ..\jeeps\gpssend.c ..\jeeps\gpsserial.c ..\jeeps\gpsusbread.c ..\jeeps\gpsusbsend.c ..\jeeps\gpsusbstub.c ..\jeeps\gpsusbwin.c ..\jeeps\gpsutil.c +set SOURCEMAG=..\maggeo.c ..\magnav.c ..\magproto.c +set SOURCE=..\xmltag.c ..\strptime.c ..\trackfilter.c ..\gdb.c ..\bcr.c ..\discard.c ..\formspec.c ..\an1.c ..\arcdist.c ..\brauniger_iq.c ..\wbt-200.c ..\cetus.c ..\coastexp.c ..\coldsync\pdb.c ..\copilot.c ..\csv_util.c ..\delgpl.c ..\duplicate.c ..\easygps.c ..\filter_vecs.c ..\garmin.c ..\garmin_tables.c ..\gcdb.c ..\geo.c ..\geoniche.c ..\glogbook.c ..\google.c ..\gpilots.c ..\gpspilot.c ..\gpx.c ..\grtcirc.c ..\hiketech.c ..\holux.c ..\hsa_ndv.c ..\html.c ..\igc.c ..\internal_styles.c ..\kml.c ..\lowranceusr.c ..\main.c ..\mapopolis.c ..\mapsend.c ..\mapsource.c ..\mkshort.c ..\navicache.c ..\netstumbler.c ..\nmea.c ..\overlay.c ..\ozi.c ..\palmdoc.c ..\pathaway.c ..\pcx.c ..\polygon.c ..\position.c ..\psitrex.c ..\psp.c ..\queue.c ..\quovadis.c ..\reverse_route.c ..\route.c ..\saroute.c ..\shape.c ..\shapelib\dbfopen.c ..\shapelib\shpopen.c ..\smplrout.c ..\sort.c ..\stackfilter.c ..\tef_xml.c ..\text.c ..\tiger.c ..\tmpro.c ..\tomtom.c ..\tpg.c ..\util.c ..\util_crc.c ..\uuid.c ..\vcf.c ..\vecs.c ..\vitosmt.c ..\vmem.c ..\waypt.c ..\xcsv.c ..\xmlgeneric.c ..\fatal.c ..\globals.c ..\cet_util.c ..\cet.c ..\nmn5.c ..\nmn4.c ..\cst.c ..\msroute.c ..\stmwpp.c ..\ignrando.c ..\tpo.c +cl /c ..\coldsync\util.c -Focoldsyncutil.obj +cl /c ..\gpsutil.c -Fogpsutil2.obj +cl /Fegpsbabel.exe %source% %sourcejeeps% %sourcemag% coldsyncutil.obj gpsutil2.obj -DVERSION=\"1\" -D__WIN32__ -DWIN32_LEAN_AND_MEAN -DNO_USB Expat\libexpat.lib +endlocal diff --git a/msvc/config.h b/msvc/config.h new file mode 100644 index 000000000..6c513d5a0 --- /dev/null +++ b/msvc/config.h @@ -0,0 +1,28 @@ +#define HAVE_LIBEXPAT 1 +#define __va_copy(ap1, ap2) ((ap1) = (ap2)) + +// This controls the capabilities of our Character Encoding Transformations. +// Undefne for minimal. +// Define to zero for the common UTF-8, ASCII and related sets. +// Define to one for everything we know. + +#undef CET_WANTED + +/* 1 to enable the CSV formats support */ +#undef CSVFMTS_ENABLED + +/* 1 to enable all the filters. */ +#undef FILTERS_ENABLED + +/* 1 to enable Palm PDB support */ +#undef PDBFMTS_ENABLED + +/* 1 to enable shapefile support */ +#undef SHAPELIB_ENABLED + +#define ZLIB_INHIBITED 1 + +/* We really should figure out some way to get this from autoconf into + * a file so that the MSVC build can pick it up + */ +#define VERSION "1.3.1" diff --git a/msvc/release.empty b/msvc/release.empty new file mode 100644 index 000000000..e69de29bb diff --git a/navicache.c b/navicache.c index c829b1c9c..43df0755d 100644 --- a/navicache.c +++ b/navicache.c @@ -17,29 +17,30 @@ */ #include "defs.h" -#if !NO_EXPAT +#include "cet_util.h" +#if HAVE_LIBEXPAT #include static XML_Parser psr; #endif static waypoint *wpt_tmp; -FILE *fd; -FILE *ofd; +static FILE *fd; +static FILE *ofd; static char *noretired = NULL; static arglist_t nav_args[] = { - {"noretired", &noretired, "Suppress retired geocaches.", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + {"noretired", &noretired, "Suppress retired geocaches", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define MYNAME "navicache" #define MY_CBUF 4096 -#if NO_EXPAT +#if ! HAVE_LIBEXPAT static void nav_rd_init(const char *fname) { @@ -107,8 +108,13 @@ nc_mkcont(const char *t) } static void -nav_start(void *data, const char *el, const char **attr) +nav_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { + const char *el; + const char **attr; + + el = xml_convert_to_char_string(xml_el); + attr = xml_convert_attrs_to_char_string(xml_attr); if (0 == strcmp(el, "CacheDetails")) { const char **ap; wpt_tmp = waypt_new(); @@ -191,10 +197,13 @@ nav_start(void *data, const char *el, const char **attr) } waypt_add(wpt_tmp); } + + xml_free_converted_attrs(attr); + xml_free_converted_string(el); } static void -nav_end(void *data, const char *el) +nav_end(void *data, const XML_Char *el) { } @@ -208,6 +217,7 @@ nav_rd_init(const char *fname) fatal(MYNAME ":Cannot create XML parser\n"); } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); XML_SetElementHandler(psr, nav_start, nav_end); } @@ -220,7 +230,7 @@ nav_read(void) while ((len = fread(buf, 1, sizeof(buf), fd))) { if (!XML_Parse(psr, buf, len, feof(fd))) { fatal(MYNAME ":Parse error at %d: %s\n", - XML_GetCurrentLineNumber(psr), + (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); } } @@ -265,4 +275,5 @@ ff_vecs_t navicache_vecs = { nav_write, NULL, nav_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/netstumbler.c b/netstumbler.c index 554d513b2..1667e5154 100644 --- a/netstumbler.c +++ b/netstumbler.c @@ -1,7 +1,7 @@ /* Read Netstumbler data files. - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net and + Copyright (C) 2004, 2005 Robert Lipe, robertlipe@usa.net and John Temples; gpsns@xargs.com This program is free software; you can redistribute it and/or modify @@ -24,12 +24,13 @@ #include "csv_util.h" #include -static FILE *file_in; +static gbfile *file_in; static char *nseicon = NULL; static char *nsneicon = NULL; static char *seicon = NULL; static char *sneicon = NULL; static char *snmac = NULL; +static int macstumbler; static void fix_netstumbler_dupes(void); @@ -38,33 +39,35 @@ static void fix_netstumbler_dupes(void); static arglist_t netstumbler_args[] = { {"nseicon", &nseicon, "Non-stealth encrypted icon name", - "Red Square", ARGTYPE_STRING }, + "Red Square", ARGTYPE_STRING, ARG_NOMINMAX }, {"nsneicon", &nsneicon, "Non-stealth non-encrypted icon name", - "Green Square", ARGTYPE_STRING }, + "Green Square", ARGTYPE_STRING, ARG_NOMINMAX }, {"seicon", &seicon, "Stealth encrypted icon name", - "Red Diamond", ARGTYPE_STRING }, + "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, {"sneicon", &sneicon, "Stealth non-encrypted icon name", - "Green Diamond", ARGTYPE_STRING }, - {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, + {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = xfopen(fname, "r", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); + macstumbler = 0; } static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); } static void data_read(void) { - char ibuf[512]; + char *ibuf; char ssid[2 + 32 + 2 + 1]; /* "( " + SSID + " )" + null */ char mac[2 + 17 + 2 + 1]; /* "( " + MAC + " )" + null */ char desc[sizeof ssid - 1 + 15 + 1]; /* room for channel/speed */ @@ -74,12 +77,15 @@ data_read(void) int stealth_num = 0, whitespace_num = 0; long flags = 0; int speed = 0, channel = 0; - struct tm tm = {0}; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); - for(; fgets(ibuf, sizeof(ibuf), file_in);) { + while ((ibuf = gbfgetstr(file_in))) { char *field; int field_num, len, i, stealth = 0; + ibuf = lrtrim(ibuf); /* A sharp in column zero might be a comment. Or it might be * something useful, like the date. */ @@ -91,6 +97,14 @@ data_read(void) tm.tm_mday = atoi(&ibuf[20]); } + /* + * Mac stumbler files are the same, except + * use DDMM.mmm instad of DD.DDDD. + */ + if (strstr(ibuf, "Creator: MacStumbler")) { + macstumbler = 1; + } + continue; } @@ -104,12 +118,18 @@ data_read(void) lat = atof(&field[2]); if (field[0] == 'S') lat = -lat; + if (macstumbler) { + lat = ddmm2degrees(lat); + } break; case 1: /* long */ lon = atof(&field[2]); if (field[0] == 'W') lon = -lon; + if (macstumbler) { + lon = ddmm2degrees(lon); + } break; case 2: /* ( SSID ) */ @@ -202,7 +222,6 @@ data_read(void) waypt_add(wpt_tmp); } - fix_netstumbler_dupes(); } @@ -255,7 +274,7 @@ fix_netstumbler_dupes(void) queue *elem, *tmp; extern queue waypt_head; const char *snptr; - char *tmp_sn, *tmp_ptr; + char *tmp_sn; unsigned long last_crc; char ssid[32 + 5 + 1]; @@ -266,9 +285,7 @@ fix_netstumbler_dupes(void) QUEUE_FOR_EACH(&waypt_head, elem, tmp) { bh->wpt = (waypoint *) elem; snptr = bh->wpt->shortname; - tmp_sn = xstrdup(snptr); - for (tmp_ptr = tmp_sn; *tmp_ptr; tmp_ptr++) - *tmp_ptr = tolower(*tmp_ptr); + tmp_sn = strlower(xstrdup(snptr)); bh->crc = get_crc32(tmp_sn, strlen(snptr)); xfree(tmp_sn); i ++; @@ -301,5 +318,6 @@ ff_vecs_t netstumbler_vecs = { data_read, NULL, NULL, - netstumbler_args + netstumbler_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/nmea.c b/nmea.c index 11515d3df..7d946e57a 100644 --- a/nmea.c +++ b/nmea.c @@ -1,22 +1,22 @@ /* - Read files containing selected NMEA 0183 sentences. - Based on information by Eino Uikkanenj + Read files containing selected NMEA 0183 sentences. + Based on information by Eino Uikkanenj - Copyright (C) 2004 Robert Lipe, robertlipe@usa.net + Copyright (C) 2004-2006 Robert Lipe, robertlipe@usa.net - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ @@ -24,6 +24,8 @@ #include #include "defs.h" +#include "gbser.h" +#include "strptime.h" /********************************************************** @@ -67,34 +69,34 @@ ' 10 300504 Date 30/05-2004 ' 11 Empty field Magnetic variation - GSA - GPS DOP and active satellites - $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39 - A Auto selection of 2D or 3D fix (M = manual) - 3 3D fix - 04,05... PRNs of satellites used for fix (space for 12) - 2.5 PDOP (dilution of precision) - 1.3 Horizontal dilution of precision (HDOP) - 2.1 Vertical dilution of precision (VDOP) - DOP is an indication of the effect of satellite geometry on - the accuracy of the fix. - - VTG - Track made good and ground speed - $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K - 054.7,T True track made good - 034.4,M Magnetic track made good - 005.5,N Ground speed, knots - 010.2,K Ground speed, Kilometers per hour - - WPL - waypoint location - $GPWPL,4917.16,N,12310.64,W,003*65 - 4917.16,N Latitude of waypoint - 12310.64,W Longitude of waypoint - 003 Waypoint ID - When a route is active, this sentence is sent once for each - waypoint in the route, in sequence. When all waypoints have - been reported, GPR00 is sent in the next data set. In any - group of sentences, only one WPL sentence, or an R00 - sentence, will be sent. + GSA - GPS DOP and active satellites + $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39 + A Auto selection of 2D or 3D fix (M = manual) + 3 3D fix + 04,05... PRNs of satellites used for fix (space for 12) + 2.5 PDOP (dilution of precision) + 1.3 Horizontal dilution of precision (HDOP) + 2.1 Vertical dilution of precision (VDOP) + DOP is an indication of the effect of satellite geometry on + the accuracy of the fix. + + VTG - Track made good and ground speed + $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K + 054.7,T True track made good + 034.4,M Magnetic track made good + 005.5,N Ground speed, knots + 010.2,K Ground speed, Kilometers per hour + + WPL - waypoint location + $GPWPL,4917.16,N,12310.64,W,003*65 + 4917.16,N Latitude of waypoint + 12310.64,W Longitude of waypoint + 003 Waypoint ID + When a route is active, this sentence is sent once for each + waypoint in the route, in sequence. When all waypoints have + been reported, GPR00 is sent in the next data set. In any + group of sentences, only one WPL sentence, or an R00 + sentence, will be sent. ' The optional checksum field consists of a "*" and two hex digits repre- @@ -108,7 +110,29 @@ * same position fix. If we see a single GGA, start ignoring GLL's and RMC's. * GLL's will also be ignored if RMC's are found and GGA's not found. */ - + +/* +Zmarties notes: + +In practice, all fields of the NMEA sentences should be treated as optional - +if the data is not available, then the field can be omitted (hence leading +to the output of two consecutive commas). + +An NMEA recording can start anywhere in the stream of data. It is therefore +necessary to discard sentences until sufficient data has been processed to +have all the necessary data to construct a waypoint. In practice, this means +discarding data until we have had the first sentence that provides the date. +(We could scan forwards in the stream of data to find the first date, and +then back apply it to all previous sentences, but that is probably more +complexity that is necessary - the lost of one waypoint at the start of the +stream can normally be tolerated.) + +If a sentence is received without a checksum, but previous sentences have +had checksums, it is best to discard that sentence. In practice, the only +time I have seen this is when the recording stops suddenly, where the last +sentence is truncated - and missing part of the line, including the checksum. +*/ + typedef enum { gp_unknown = 0, gpgga, @@ -116,13 +140,24 @@ typedef enum { gprmc } preferred_posn_type; -static FILE *file_in; -static FILE *file_out; +enum { + rm_unknown = 0, + rm_serial, + rm_file +} read_mode; + +static gbfile *file_in, *file_out; static route_head *trk_head; -static void *mkshort_handle; +static short_handle mkshort_handle; static preferred_posn_type posn_type; -static time_t creation_time; -static waypoint * curr_waypt =NULL; +static struct tm tm; +static waypoint * curr_waypt = NULL; +static waypoint * last_waypt = NULL; +static void * gbser_handle; +static const char *posn_fname; + +static int without_date; /* number of created trackpoints without a valid date */ +static struct tm opt_tm; /* converted "date" parameter */ #define MYNAME "nmea" @@ -130,23 +165,41 @@ static const double kts2mps =0.51444444444444444; /* knots to m/s */ static const double kmh2mps =0.27777777777777778; /* km/h to m/s */ static char *dogprmc = NULL; -static char *nogpgga = NULL; -static char *nogpvtg = NULL; -static char *nogpgsa = NULL; +static char *dogpgga = NULL; +static char *dogpvtg = NULL; +static char *dogpgsa = NULL; +static char *snlenopt = NULL; +static char *optdate = NULL; +static char *getposnarg = NULL; +static char *opt_sleep = NULL; +static char *opt_baud = NULL; +static long sleepus = 0; +static int getposn; + +static time_t last_time = -1; +static double last_read_time; /* Last timestamp of GGA or PRMC */ + +static waypoint * nmea_rd_posn(posn_status *); +static void nmea_rd_posn_init(const char *fname); arglist_t nmea_args[] = { - {"gprmc", &dogprmc, "Write GPRMC sentences", NULL, ARGTYPE_BOOL }, - {"nogpgga", &nogpgga, "Don't write GPGGA sentences", NULL, ARGTYPE_BOOL }, - {"nogpvtg", &nogpvtg, "Don't write GPVTG sentences", NULL, ARGTYPE_BOOL }, - {"nogpgsa", &nogpgsa, "Don't write GPGSA sentences", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0 } + {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" }, + {"gprmc", &dogprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgga", &dogpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpvtg", &dogpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgsa", &dogpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { "get_posn", &getposnarg, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + ARG_TERMINATOR }; - /* * Slightly different than the Magellan checksum fn. */ -static int +int nmea_cksum(const char *const buf) { int x = 0 ; @@ -161,39 +214,108 @@ nmea_cksum(const char *const buf) static void nmea_rd_init(const char *fname) { - file_in = xfopen(fname, "r", MYNAME); + curr_waypt = NULL; + last_waypt = NULL; + + if (getposnarg) { + getposn = 1; + } + + /* A special case hack that gets our current position and returns + * it as one waypoint. + */ + if (getposn) { + waypoint *wpt; + posn_status st; + nmea_rd_posn_init(fname); + wpt = nmea_rd_posn(&st); + if (!wpt) { + return; + } + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("Position"); + waypt_add(wpt); + return; + } + + read_mode = rm_file; + file_in = gbfopen(fname, "rb", MYNAME); } static void nmea_rd_deinit(void) { - fclose(file_in); + switch(read_mode) { + case rm_serial: + gbser_deinit(gbser_handle); + break; + case rm_file: + gbfclose(file_in); + file_in = NULL; + break; + default: + fatal("nmea_rd_deinit: illegal read_mode.\n"); + break; + } } static void nmea_wr_init(const char *portname) { - file_out = xfopen(portname, "w+", MYNAME); + file_out = gbfopen(portname, "w+", MYNAME); + + if ( opt_sleep ) { + if ( *opt_sleep ) { + sleepus = 1e6 * atof(opt_sleep); + } + else { + sleepus = -1; + } + } mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, 6); + setshort_length(mkshort_handle, atoi(snlenopt)); } static void nmea_wr_deinit(void) { - fclose(file_out); - mkshort_del_handle(mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } -void +static void +nmea_set_waypoint_time(waypoint *wpt, struct tm *time) +{ + if (time->tm_year == 0) + { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + if (wpt->centiseconds == 0) + { + wpt->centiseconds++; + without_date++; + } + } + else + { + wpt->creation_time = mkgmtime(time); + if (wpt->centiseconds != 0) + { + wpt->centiseconds = 0; + without_date--; + } + } +} + +static void gpgll_parse(char *ibuf) { double latdeg, lngdeg; char lngdir, latdir; int hms; char valid; - struct tm tm; waypoint *waypt; if (trk_head == NULL) { @@ -201,8 +323,6 @@ gpgll_parse(char *ibuf) track_add_head(trk_head); } - memset(&tm, 0, sizeof(tm)); - sscanf(ibuf,"$GPGLL,%lf,%c,%lf,%c,%d,%c,", &latdeg,&latdir, &lngdeg,&lngdir, @@ -210,15 +330,18 @@ gpgll_parse(char *ibuf) if (valid != 'A') return; + tm.tm_sec = hms % 100; hms = hms / 100; tm.tm_min = hms % 100; hms = hms / 100; tm.tm_hour = hms % 100; + last_read_time = hms; + waypt = waypt_new(); - waypt->creation_time = creation_time; + nmea_set_waypoint_time(waypt, &tm); if (latdir == 'S') latdeg = -latdeg; waypt->latitude = ddmm2degrees(latdeg); @@ -227,7 +350,6 @@ gpgll_parse(char *ibuf) waypt->longitude = ddmm2degrees(lngdeg); curr_waypt = waypt; - route_add_wpt(trk_head, waypt); } static void @@ -236,7 +358,6 @@ gpgga_parse(char *ibuf) double latdeg, lngdeg; char lngdir, latdir; double hms; - struct tm tm; double alt; int fix; int nsats; @@ -249,17 +370,22 @@ gpgga_parse(char *ibuf) track_add_head(trk_head); } - memset(&tm, 0, sizeof(tm)); - sscanf(ibuf,"$GPGGA,%lf,%lf,%c,%lf,%c,%d,%d,%lf,%lf,%c", &hms, &latdeg,&latdir, &lngdeg,&lngdir, &fix,&nsats,&hdop,&alt,&altunits); - if (fix == 0) { + /* + * In serial mode, allow the fix with an invalid position through + * as serial units will often spit a remembered position up and + * that is more comfortable than nothing at all... + */ + if ((fix == 0) && (read_mode != rm_serial)) { return; } + last_read_time = hms; + tm.tm_sec = (long) hms % 100; hms = hms / 100; tm.tm_min = (long) hms % 100; @@ -268,7 +394,7 @@ gpgga_parse(char *ibuf) waypt = waypt_new(); - waypt->creation_time = creation_time; + nmea_set_waypoint_time(waypt, &tm); if (latdir == 'S') latdeg = -latdeg; waypt->latitude = ddmm2degrees(latdeg); @@ -282,18 +408,22 @@ gpgga_parse(char *ibuf) waypt->hdop = hdop; - if (fix==1) { - waypt->fix = (nsats>3)?(fix_3d):(fix_2d); - } - else if (fix==2) - { - waypt->fix = fix_dgps; + switch (fix) { + case 0: + waypt->fix = fix_none; + break; + case 1: + waypt->fix = (nsats>3)?(fix_3d):(fix_2d); + break; + case 2: + waypt->fix = fix_dgps; + break; + case 3: + waypt->fix = fix_pps; + break; } curr_waypt = waypt; - route_add_wpt(trk_head, waypt); - - } static void @@ -304,7 +434,6 @@ gprmc_parse(char *ibuf) double hms; char fix; unsigned int dmy; - struct tm tm; double speed,course; waypoint *waypt; @@ -313,12 +442,17 @@ gprmc_parse(char *ibuf) track_add_head(trk_head); } - memset(&tm, 0, sizeof(tm)); - sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", &hms, &fix, &latdeg, &latdir, &lngdeg, &lngdir, &speed, &course, &dmy); + + if (fix != 'A') { + /* ignore this fix - it is invalid */ + return; + } + + last_read_time = hms; tm.tm_sec = (long) hms % 100; hms = hms / 100; @@ -331,7 +465,6 @@ gprmc_parse(char *ibuf) tm.tm_mon = dmy % 100 - 1; dmy = dmy / 100; tm.tm_mday = dmy; - creation_time = mkgmtime(&tm); if (posn_type == gpgga) { /* capture useful data update and exit */ @@ -340,6 +473,9 @@ gprmc_parse(char *ibuf) curr_waypt->speed = speed*kts2mps; if (curr_waypt->course<=0) curr_waypt->course = course; + /* The change of date wasn't recorded when + * going from 235959 to 000000. */ + nmea_set_waypoint_time(curr_waypt, &tm); } return; } @@ -350,7 +486,7 @@ gprmc_parse(char *ibuf) waypt->course = course; - waypt->creation_time = creation_time; + nmea_set_waypoint_time(waypt, &tm); if (latdir == 'S') latdeg = -latdeg; waypt->latitude = ddmm2degrees(latdeg); @@ -359,7 +495,6 @@ gprmc_parse(char *ibuf) waypt->longitude = ddmm2degrees(lngdeg); curr_waypt = waypt; - route_add_wpt(trk_head, waypt); } static void @@ -368,12 +503,12 @@ gpwpl_parse(char *ibuf) waypoint *waypt; double latdeg, lngdeg; char latdir, lngdir; - char sname[7]; + char sname[99]; sscanf(ibuf,"$GPWPL,%lf,%c,%lf,%c,%[^*]", &latdeg,&latdir, &lngdeg,&lngdir, - &sname); + sname); waypt = waypt_new(); @@ -394,9 +529,7 @@ gpzda_parse(char *ibuf) { double hms; int dd, mm, yy, lclhrs, lclmins; - struct tm tm; - memset(&tm, 0, sizeof(tm)); sscanf(ibuf,"$GPZDA,%lf,%d,%d,%d,%d,%d", &hms, &dd, &mm, &yy, &lclhrs, &lclmins); tm.tm_sec = (int) hms % 100; @@ -405,7 +538,6 @@ gpzda_parse(char *ibuf) tm.tm_mday = dd; tm.tm_mon = mm - 1; tm.tm_year = yy - 1900; - creation_time = mkgmtime(&tm); } static void @@ -469,7 +601,7 @@ gpvtg_parse(char *ibuf) char cn; double speed_k; char ck; - + sscanf(ibuf,"$GPVTG,%f,%c,%f,%c,%lf,%c,%lf,%c", &course,&ct,&magcourse,&cm,&speed_n,&cn,&speed_k,&ck); @@ -485,69 +617,251 @@ gpvtg_parse(char *ibuf) } +static void +nmea_fix_timestamps(route_head *track) +{ + if ((trk_head == NULL) || (without_date == 0)) return; + + if (tm.tm_year == 0) + { + queue *elem, *temp; + waypoint *prev = NULL; + time_t delta_tm; + + if (optdate == NULL) + { + warning(MYNAME ": No date found within track (all points dropped)!\n"); + warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n"); + track_del_head(track); + return; + } + delta_tm = mkgmtime(&opt_tm); + + QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) + { + waypoint *wpt = (waypoint *)elem; + + wpt->creation_time += delta_tm; + if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) /* go over midnight ? */ + { + delta_tm += SECONDS_PER_DAY; + wpt->creation_time += SECONDS_PER_DAY; + } + prev = wpt; + } + } + else + { + time_t prev; + queue *elem; + + tm.tm_hour = 23; /* last date found */ + tm.tm_min = 59; + tm.tm_sec = 59; + + prev = mkgmtime(&tm); + + /* go backward through the track and complete timestamps */ + + for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) + { + waypoint *wpt = (waypoint *)elem; + + if (wpt->centiseconds != 0) + { + time_t dt; + + wpt->centiseconds = 0; /* reset flag */ + + dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY; + wpt->creation_time += dt; + if (wpt->creation_time > prev) + wpt->creation_time+=SECONDS_PER_DAY; + } + prev = wpt->creation_time; + } + } +} + +void +nmea_parse_one_line(char *ibuf) +{ + int had_checksum = 0; + char *ck; + int ckval, ckcmp; + char *tbuf = lrtrim(ibuf); + + if (*tbuf != '$') return; + + ck = strrchr(tbuf, '*'); + if (ck != NULL) { + *ck = '\0'; + ckval = nmea_cksum(&tbuf[1]); + *ck = '*'; + ck++; + sscanf(ck, "%2X", &ckcmp); + if (ckval != ckcmp) { +#if 0 + printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); + printf("NMEA %s\n", tbuf); +#endif + return; + } + + had_checksum = 1; + } + else if (had_checksum) { + /* we have had a checksum on all previous sentences, but not on this + one, which probably indicates this line is truncated */ + had_checksum = 0; + return; + } + + /* @@@ zmarties: The parse routines all assume all fields are present, but + the NMEA format allows any field to be missed out if there is no data + for that field. Rather than change all the parse routines, we first + substitute a default value of zero for any missing field. + */ + if (strstr(tbuf, ",,")) + { + tbuf = gstrsub(tbuf, ",,", ",0,"); + } + + if (0 == strncmp(tbuf, "$GPWPL,", 7)) { + gpwpl_parse(tbuf); + } else + if (dogpgga && (0 == strncmp(tbuf, "$GPGGA,", 7))) { + posn_type = gpgga; + gpgga_parse(tbuf); + } else + if (dogprmc && (0 == strncmp(tbuf, "$GPRMC,", 7))) { + if (posn_type != gpgga) { + posn_type = gprmc; + } + /* + * Always call gprmc_parse() because like GPZDA + * it contains the full date. + */ + gprmc_parse(tbuf); + } else + if (0 == strncmp(tbuf, "$GPGLL,", 7)) { + if ((posn_type != gpgga) && (posn_type != gprmc)) { + gpgll_parse(tbuf); + } + } else + if (0 == strncmp(tbuf, "$GPZDA,",7)) { + gpzda_parse(tbuf); + } else + if (dogpvtg && (0 == strncmp(tbuf, "$GPVTG,",7))) { + gpvtg_parse(tbuf); /* speed and course */ + } else + if (dogpgsa && (0 == strncmp(tbuf, "$GPGSA,",7))) { + gpgsa_parse(tbuf); /* GPS fix */ + } + + if (tbuf != ibuf) { + /* clear up the dynamic buffer we used because substition was required */ + xfree(tbuf); + } +} static void nmea_read(void) { - char ibuf[1024]; + char *ibuf; char *ck; - int ckval, ckcmp; - struct tm tm; + double lt = -1; + + posn_type = gp_unknown; + trk_head = NULL; + without_date = 0; + memset(&tm, 0, sizeof(tm)); + opt_tm = tm; - creation_time = mkgmtime(&tm) + current_time(); + /* This was done in rd_init() */ + if (getposn) { + return; + } + + if (optdate) + { + memset(&opt_tm, 0, sizeof(opt_tm)); + + ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); + if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) + fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); + else if (opt_tm.tm_year < 70) + fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); + } curr_waypt = NULL; - while (fgets(ibuf, sizeof(ibuf), file_in)) { - ck = strrchr(ibuf, '*'); - if (ck != NULL) { - *ck = '\0'; - ckval = nmea_cksum(&ibuf[1]); - *ck = '*'; - ck++; - sscanf(ck, "%2X", &ckcmp); - if (ckval != ckcmp) { -#if 0 - printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); - printf("NMEA %s\n", ibuf); -#endif - continue; + while ((ibuf = gbfgetstr(file_in))) { + nmea_parse_one_line(ibuf); + if (lt != last_read_time && curr_waypt && trk_head) { + if (curr_waypt != last_waypt) { + track_add_wpt(trk_head, curr_waypt); + last_waypt = curr_waypt; } + lt = last_read_time; } - if (0 == strncmp(ibuf, "$GPWPL,", 7)) { - gpwpl_parse(ibuf); - } else - if (0 == strncmp(ibuf, "$GPGGA,", 7)) { - posn_type = gpgga; - gpgga_parse(ibuf); - } else - if (0 == strncmp(ibuf, "$GPRMC,", 7)) { - if (posn_type != gpgga) { - posn_type = gprmc; - } - /* - * Allways call gprmc_parse() because like GPZDA - * it contains the full date. - */ - gprmc_parse(ibuf); - } else - if (0 == strncmp(ibuf, "$GPGLL,", 7)) { - if ((posn_type != gpgga) && (posn_type != gprmc)) { - gpgll_parse(ibuf); - } - } else - if (0 == strncmp(ibuf, "$GPZDA,",7)) { - gpzda_parse(ibuf); - } else - if (0 == strncmp(ibuf, "$GPVTG,",7)) { - gpvtg_parse(ibuf); /* speed and course */ - } else - if (0 == strncmp(ibuf, "$GPGSA,",7)) { - gpgsa_parse(ibuf); /* GPS fix */ + } + + /* try to complete date-less trackpoints */ + nmea_fix_timestamps(trk_head); +} + +void +nmea_rd_posn_init(const char *fname) +{ + if ((gbser_handle = gbser_init(fname)) != NULL) { + read_mode = rm_serial; + gbser_set_speed(gbser_handle, 4800); + } else { + fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); + } + + if (opt_baud) { + if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) { + fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud); } } + posn_fname = fname; } +static waypoint * +nmea_rd_posn(posn_status *posn_status) +{ + char ibuf[1024]; + static double lt = -1; + int i; + + /* + * Read a handful of sentences, collecting the best info we + * can. If the timestamp changes (indicating the sequence is + * about to restart and thus the one we're collecting isn't going + * to get any better than we now have) hand that back to the caller. + */ + for (i = 0; i < 10; i++) { + int rv; + ibuf[0] = 0; + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d); + if (global_opts.debug_level > 1) { + warning( "READ: %s\n", ibuf); + } + if (rv < 0) { + fatal(MYNAME ": No data received on %s.\n", posn_fname); + } + nmea_parse_one_line(ibuf); + if (lt != last_read_time) { + if (last_read_time) { + lt = last_read_time; + return waypt_dupe(curr_waypt); + } + } + } + return NULL; +} static void nmea_wayptpr(const waypoint *wpt) @@ -559,7 +873,11 @@ nmea_wayptpr(const waypoint *wpt) lat = degrees2ddmm(wpt->latitude); lon = degrees2ddmm(wpt->longitude); - s = mkshort(mkshort_handle, wpt->shortname); + if (global_opts.synthesize_shortnames) + s = mkshort_from_wpt(mkshort_handle, wpt); + else { + s = mkshort(mkshort_handle, wpt->shortname); + } snprintf(obuf, sizeof(obuf), "GPWPL,%08.3f,%c,%09.3f,%c,%s", fabs(lat), lat < 0 ? 'S' : 'N', @@ -567,12 +885,22 @@ nmea_wayptpr(const waypoint *wpt) ); cksum = nmea_cksum(obuf); - fprintf(file_out, "$%s*%02X\n", obuf, cksum); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + if (sleepus >= 0) { + gbfflush(file_out); + gb_sleep(sleepus); + } xfree(s); } +void +nmea_track_init(const route_head *rte) +{ + last_time = -1; +} + void nmea_trackpt_pr(const waypoint *wpt) { @@ -581,17 +909,35 @@ nmea_trackpt_pr(const waypoint *wpt) double lat,lon; int cksum; struct tm *tm; - int hms; + time_t hms; + time_t ymd; + + if ( opt_sleep ) { + gbfflush( file_out ); + if ( last_time > 0 ) { + if ( sleepus >= 0 ) { + gb_sleep( sleepus ); + } + else { + long wait_time = wpt->creation_time - last_time; + if ( wait_time > 0 ) { + gb_sleep( wait_time * 1000000 ); + } + } + } + last_time = wpt->creation_time; + } lat = degrees2ddmm(wpt->latitude); lon = degrees2ddmm(wpt->longitude); tm = gmtime(&wpt->creation_time); if ( tm ) { - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + - tm->tm_sec; + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; } else { hms = 0; + ymd = 0; } switch (wpt->fix) @@ -603,25 +949,28 @@ nmea_trackpt_pr(const waypoint *wpt) case fix_2d: fix='1'; break; + case fix_pps: + fix='3'; + break; default: fix='0'; } if (dogprmc) { snprintf(obuf, sizeof(obuf), "GPRMC,%06d,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,", - hms, + (int) hms, fix=='0' ? 'V' : 'A', fabs(lat), lat < 0 ? 'S' : 'N', fabs(lon), lon < 0 ? 'W' : 'E', (wpt->speed>0)?(wpt->speed / kts2mps):(0), (wpt->course>=0)?(wpt->course):(0), - tm->tm_mday*10000+(tm->tm_mon+1)*100+tm->tm_year); + (int) ymd); cksum = nmea_cksum(obuf); - fprintf(file_out, "$%s*%02X\n", obuf, cksum); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); } - if (!nogpgga) { + if (dogpgga) { snprintf(obuf, sizeof(obuf), "GPGGA,%06d,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,0.0,M,,", - hms, + (int) hms, fabs(lat), lat < 0 ? 'S' : 'N', fabs(lon), lon < 0 ? 'W' : 'E', fix, @@ -629,19 +978,19 @@ nmea_trackpt_pr(const waypoint *wpt) (wpt->hdop>0)?(wpt->hdop):(0.0), wpt->altitude == unknown_alt ? 0 : wpt->altitude); cksum = nmea_cksum(obuf); - fprintf(file_out, "$%s*%02X\n", obuf, cksum); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); } - if ((!nogpvtg) && ((wpt->course>=0) || (wpt->speed>0))) { + if ((dogpvtg) && ((wpt->course>=0) || (wpt->speed>0))) { snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K", (wpt->course>=0)?(wpt->course):(0), (wpt->speed>0)?(wpt->speed / kts2mps):(0), (wpt->speed>0)?(wpt->speed / kmh2mps):(0) ); cksum = nmea_cksum(obuf); - fprintf(file_out, "$%s*%02X\n", obuf, cksum); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); } - if ((!nogpgsa) && (wpt->fix!=fix_unknown)) { + if ((dogpgsa) && (wpt->fix!=fix_unknown)) { switch (wpt->fix) { @@ -662,7 +1011,7 @@ nmea_trackpt_pr(const waypoint *wpt) (wpt->hdop>0)?(wpt->hdop):(0), (wpt->vdop>0)?(wpt->vdop):(0) ); cksum = nmea_cksum(obuf); - fprintf(file_out, "$%s*%02X\n", obuf, cksum); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); } } @@ -670,7 +1019,7 @@ static void nmea_write(void) { waypt_disp_all(nmea_wayptpr); - track_disp_all(NULL, NULL, nmea_trackpt_pr); + track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr); } ff_vecs_t nmea_vecs = { @@ -683,5 +1032,7 @@ ff_vecs_t nmea_vecs = { nmea_read, nmea_write, NULL, - nmea_args + nmea_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit, NULL, NULL, NULL } }; diff --git a/nmn4.c b/nmn4.c new file mode 100644 index 000000000..e608e373c --- /dev/null +++ b/nmn4.c @@ -0,0 +1,322 @@ + /* + + Support for Navigon Mobile Navigator .rte files. + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + line structure, items delimited by '|' + +-|-|17|-|ZIP-Code|City|ZIP-Code2|Street|No.|-|-|longitude|latitude|-|-| + 0D0A + +*/ + +#include "defs.h" +#include "csv_util.h" +#include +#include +#include +#include + +static gbfile *fin, *fout; +static int curr_rte_num, target_rte_num; + +#define MYNAME "navigon" + +static char *index_opt; + +static +arglist_t nmn4_args[] = { + {"index", &index_opt, "Index of route to write (if more the one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +/* helpers */ + +static char * +nmn4_concat(char *arg0, ...) +{ + va_list args; + char *src, *res; + + res = NULL; + va_start(args, arg0); + src = (char *)arg0; + + while (src != NULL) + { + char *c = lrtrim(src); + + if (*c != '\0') + { + if (res == NULL) + res = xstrdup(c); + else + { + res = xstrappend(res, " "); + res = xstrappend(res, c); + } + } + xfree(src); + src = va_arg(args, char *); + } + va_end(args); + + return res; +} + +static void +nmn4_check_line(char *line) +{ + char *c = line; + int i = 0; + while ((c = strchr(c, '|'))) + { + c++; + i++; + } + is_fatal((i != 15), + MYNAME ": Invalid or unknown structure!"); +} + +static void +nmn4_read_data(void) +{ + char *buff; + char *str, *c; + int column; + + char *zip1, *zip2, *city, *street, *number; + route_head *route; + waypoint *wpt; + + route = route_head_alloc(); + route_add_head(route); + + while ((buff = gbfgetstr(fin))) + { + str = buff = lrtrim(buff); + if (*buff == '\0') continue; + + nmn4_check_line(buff); + + /* for a quiet compiler */ + zip1 = zip2 = city = street = number = NULL; + + wpt = waypt_new(); + + column = -1; + c = csv_lineparse(str, "|", "", column++); + while (c != NULL) + { + switch(column) + { + case 0: /* "-" */ /* unknown fields for the moment */ + case 1: /* "-" */ + case 2: /* "-" */ + case 3: /* "-" */ + case 9: /* "-" */ + case 10: /* "-" */ + case 13: /* "-" */ + case 14: /* "-" */ + case 15: /* "" */ + break; + + case 4: /* ZIP Code */ + if (*c != '-') + zip1 = xstrdup(c); + else + zip1 = xstrdup(""); + break; + + case 5: /* City */ + if (*c != '-') + city = xstrdup(c); + else + city = xstrdup(""); + break; + + case 6: /* ZIP Code -2- */ + if (*c != '-') + zip2 = xstrdup(c); + else + zip2 = xstrdup(""); + break; + + case 7: /* Street */ + if (*c != '-') + street = xstrdup(c); + else + street = xstrdup(""); + break; + + case 8: /* Number */ + if (*c != '-') + number = xstrdup(c); + else + number = xstrdup(""); + + /* + This is our final index + All stuff for generating names or comments + is hold locally. + + We don't have fields for street, city or zip-code. + Instead we construct a description from that. + */ + + if (strcmp(zip1, zip2) == 0) *zip2 = '\0'; + if (*city != '\0') + { + /* + if any field following city has a value, add a comma to city + */ + if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0')) + city = xstrappend(city, ","); + } + + /* concats all fields to one string and release */ + wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL); + break; + + case 11: /* longitude */ + sscanf(c, "%lf", &wpt->longitude); + break; + + case 12: /* latitude */ + sscanf(c, "%lf", &wpt->latitude); + break; + + } + c = csv_lineparse(NULL, "|", "", column++); + } + route_add_wpt(route, wpt); + } +} + +static void +nmn4_route_hdr(const route_head *route) +{ + curr_rte_num++; +} + +static void +nmn4_route_tlr(const route_head *rte) +{ +} + +static void +nmn4_write_waypt(const waypoint *wpt) +{ + char city[128], street[128], zipc[32], number[32]; + + if (curr_rte_num != target_rte_num) return; + + strncpy(city, "-", sizeof(city)); + strncpy(street, "-", sizeof(street)); + strncpy(zipc, "-", sizeof(zipc)); + strncpy(number, "-", sizeof(number)); + + /* + Population of specific data used by Navigon may come in the + future or it may be impossible. We currently output only the + coordinates in the output, but this is sufficient for Navigon. + + The coordinates are the only item we are about guaranteed to have + when converting to any from any format, so we leave the other + fields unpopulated. So i have to pay Navigon a compliment for + implementing a simple data exchange. + */ + + gbfprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n", + zipc, city, zipc, street, number, + wpt->longitude, wpt->latitude); +} + +static void +nmn4_write_data(void) +{ + + target_rte_num = 1; + + if (index_opt != NULL) + { + target_rte_num = atoi(index_opt); + is_fatal(((target_rte_num > (int) route_count()) || (target_rte_num < 1)), + MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count()); + } + + curr_rte_num = 0; + route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt); +} + + +/* %%% global callbacks %%% */ + +static void +nmn4_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); +} + +static void +nmn4_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +nmn4_read(void) +{ + nmn4_read_data(); +} + +static void +nmn4_wr_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); +} + +static void +nmn4_wr_deinit(void) +{ + gbfclose(fout); +} + +static void +nmn4_write(void) +{ + nmn4_write_data(); +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t nmn4_vecs = { + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, + nmn4_rd_init, + nmn4_wr_init, + nmn4_rd_deinit, + nmn4_wr_deinit, + nmn4_read, + nmn4_write, + NULL, + nmn4_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ +}; diff --git a/nukedata.c b/nukedata.c new file mode 100644 index 000000000..6dc8fccbb --- /dev/null +++ b/nukedata.c @@ -0,0 +1,64 @@ +/* + + nukedata: remove all (waypoint|tracks|routes) from the stream. + + Copyright (C) 2005 Robert Lipe robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED +#define MYNAME "nukedata" + +static char *nukewpts, *nuketrks, *nukertes; + +static +arglist_t nuke_args[] = { + {"waypoints", &nukewpts, "Remove all waypoints from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + {"tracks", &nuketrks, "Remove all tracks from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + {"routes", &nukertes, "Remove all routes from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + ARG_TERMINATOR +}; + +static void +nuke_process(void) +{ + if (*nukewpts != '0') { + waypt_flush_all(); + } + if (*nuketrks != '0') { + route_flush_all_tracks(); + } + if (*nukertes != '0') { + route_flush_all_routes(); + } +} + +filter_vecs_t nuke_vecs = { + NULL, + nuke_process, + NULL, + NULL, + nuke_args +}; + +#endif diff --git a/overlay.c b/overlay.c index b6b69518b..fdf3a0f68 100644 --- a/overlay.c +++ b/overlay.c @@ -28,7 +28,7 @@ #include "defs.h" #include "grtcirc.h" -static void *mkshort_handle; +static short_handle mkshort_handle; #define MYNAME "overlay" #define PARAMETER_FILE "overlay.def" @@ -78,26 +78,26 @@ static char *govl_file_s = NULL; static arglist_t ovl_args[] = { { "col", &govl_col_s, "color index [1-9] for routes", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, "1", "9" }, { "size", &govl_size_s, "size index [101-] for routes", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, "101", NULL }, { "mapname", &govl_mapname, "name of map", - NULL, ARGTYPE_STRING }, + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, { "zoomfc", &govl_zoomfc_s, "zoom factor of map in %", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, ARG_NOMINMAX }, { "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, ARG_NOMINMAX }, { "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, "1", "9" }, { "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, "101", NULL }, { "font", &govl_font_s, "font index [1-] for waypoint names", - NULL, ARGTYPE_INT }, + NULL, ARGTYPE_INT, "1", NULL }, { "txttrans", &govl_txttrans_s, "set text background to transparent", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, { "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)", - NULL, ARGTYPE_STRING }, - { 0, 0, 0, 0, 0 } + NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; @@ -424,11 +424,11 @@ void ovl_read_parameter(char *fname) pstr = strtok(NULL,"\n"); if (p->argtype==ARGTYPE_BOOL) { - *(p->argval) = atoi(pstr) ? strdup(pstr) : NULL; + *(p->argval) = atoi(pstr) ? xstrdup(pstr) : NULL; } else { - *(p->argval) = strdup(pstr); + *(p->argval) = xstrdup(pstr); } break; } @@ -580,8 +580,8 @@ static void symbol_deinit(const route_head *hd) QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) { waypointp = (waypoint *) elem; - lat2 = waypointp->latitude *M_PI/180.0 ; - lon2 = waypointp->longitude*M_PI/180.0 ; + lat2 = RAD(waypointp->latitude); + lon2 = RAD(waypointp->longitude); if (i) { d = gcdist(lat1, lon1, lat2, lon2 ); @@ -604,8 +604,8 @@ static void symbol_deinit(const route_head *hd) while (elem!=&(hd->waypoint_list) && ddlatitude *M_PI/180.0; - lon2 = waypointp->longitude*M_PI/180.0; + lat2 = RAD(waypointp->latitude); + lon2 = RAD(waypointp->longitude); if (i) { d = gcdist(lat1, lon1, lat2, lon2 ); @@ -621,7 +621,7 @@ static void symbol_deinit(const route_head *hd) // d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) ); dd = acos( (sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)) ); if (lone 360.0 ? dd - 360.0 : dd; // normalizing @@ -629,7 +629,7 @@ static void symbol_deinit(const route_head *hd) /* name of route */ /* plot text at the last point of route */ govl_dir = dd; // approximated text rotation, correct value must be the azimuth in UTM - symbol_text(lon1*180.0/M_PI,lat1*180.0/M_PI,hd->rte_name,govl_group_cnt); + symbol_text(DEG(lon1),DEG(lat1),hd->rte_name,govl_group_cnt); govl_dir = 0.0; // restore } @@ -698,5 +698,6 @@ ff_vecs_t overlay_vecs = { ovl_read, ovl_write, NULL, - ovl_args + ovl_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/ozi.c b/ozi.c index b655f61a2..b33ccd89a 100644 --- a/ozi.c +++ b/ozi.c @@ -28,11 +28,17 @@ #include /* for floor */ #define MYNAME "OZI" +#define BADCHARS ",\n" +typedef struct { + format_specific_data fs; + int fgcolor; + int bgcolor; +} ozi_fsdata; -static FILE *file_in; -static FILE *file_out; -static void *mkshort_handle; + +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; static route_head *trk_head; static route_head *rte_head; @@ -44,24 +50,64 @@ static char *snlenopt = NULL; static char *snwhiteopt = NULL; static char *snupperopt = NULL; static char *snuniqueopt = NULL; +static char *wptfgcolor = NULL; +static char *wptbgcolor = NULL; + + static arglist_t ozi_args[] = { {"snlen", &snlenopt, "Max synthesized shortname length", - NULL, ARGTYPE_INT}, - {"snwhite", &snwhiteopt, "(0/1) Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL}, - {"snupper", &snupperopt, "(0/1) UPPERCASE synth. shortnames", - NULL, ARGTYPE_BOOL}, - {"snunique", &snuniqueopt, "(0/1) Make synth. shortnames unique", - NULL, ARGTYPE_BOOL}, - {0, 0, 0, 0, 0} + "32", ARGTYPE_INT, "1", NULL}, + {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"wptfgcolor", &wptfgcolor, "Waypoint foreground color", + "black", ARGTYPE_STRING, ARG_NOMINMAX}, + {"wptbgcolor", &wptbgcolor, "Waypoint background color", + "yellow", ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; -gpsdata_type ozi_objective; +static gpsdata_type ozi_objective; static char *ozi_ofname = NULL; +static void +ozi_copy_fsdata(ozi_fsdata **dest, ozi_fsdata *src) +{ + /* No strings to mess with. Straight forward copy. */ + *dest = (void *)xmalloc(sizeof(*src)); + **dest = *src; + (*dest)->fs.next = NULL; +} + +static void +ozi_free_fsdata(void *fsdata) +{ + xfree(fsdata); +} + +static +ozi_fsdata * +ozi_alloc_fsdata(void) +{ + ozi_fsdata *fsdata = xcalloc(sizeof(*fsdata), 1); + fsdata->fs.type = FS_OZI; + fsdata->fs.copy = (fs_copy) ozi_copy_fsdata; + fsdata->fs.destroy = ozi_free_fsdata; + fsdata->fs.convert = NULL; + + /* Provide defaults via command line defaults */ + fsdata->fgcolor = color_to_bbggrr(wptfgcolor); + fsdata->bgcolor = color_to_bbggrr(wptbgcolor); + + return fsdata; +} + static void ozi_openfile(char *fname) { char *c, *tmpname; @@ -69,9 +115,14 @@ ozi_openfile(char *fname) { char buff[32]; /* if we're doing multi-track output, sequence the filenames like: - * mytrack.plt, mytrack-1.plt... + * mytrack.plt, mytrack-1.plt...unless we're writing to stdout. */ + if (0 == strcmp(fname, "-")) { + file_out = gbfopen(fname, "wb", MYNAME); + return; + } + if ((track_out_count) && (ozi_objective == trkdata)) { sprintf(buff, "-%d", track_out_count); } else { @@ -102,11 +153,11 @@ ozi_openfile(char *fname) { /* re-open file_out with the new filename */ if (file_out) { - fclose(file_out); + gbfclose(file_out); file_out = NULL; } - file_out = xfopen(tmpname, "wb", MYNAME); + file_out = gbfopen(tmpname, "wb", MYNAME); xfree(tmpname); @@ -121,11 +172,12 @@ ozi_track_hdr(const route_head * rte) "WGS 84\r\n" "Altitude is in Feet\r\n" "Reserved 3\r\n" - "0,2,255,ComplimentsOfGPSBabel,0,0,2,8421376\r\n" + "0,2,255,%s,0,0,2,8421376\r\n" "0\r\n"; ozi_openfile(ozi_ofname); - fprintf(file_out, ozi_trk_header); + gbfprintf(file_out, ozi_trk_header, + rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel"); track_out_count++; } @@ -141,10 +193,10 @@ ozi_track_disp(const waypoint * waypointp) if (waypointp->altitude == unknown_alt) { alt_feet = -777; } else { - alt_feet = (waypointp->altitude * 3.2808); + alt_feet = METERS_TO_FEET(waypointp->altitude); } - fprintf(file_out, "%.6f,%.6f,0,%.0f,%.5f,,\r\n", + gbfprintf(file_out, "%.6f,%.6f,0,%.0f,%.5f,,\r\n", waypointp->latitude, waypointp->longitude, alt_feet, ozi_time); } @@ -170,7 +222,7 @@ ozi_route_hdr(const route_head * rte) /* prologue on 1st pass only */ if (route_out_count == 0) { - fprintf(file_out, ozi_route_header); + gbfprintf(file_out, ozi_route_header); } route_out_count++; @@ -188,7 +240,7 @@ ozi_route_hdr(const route_head * rte) * R, 1, ICP GALHETA,, 16711680 */ - fprintf(file_out, "R,%d,%s,%s,\r\n", + gbfprintf(file_out, "R,%d,%s,%s,\r\n", route_out_count, rte->rte_name ? rte->rte_name : "", rte->rte_desc ? rte->rte_desc : ""); @@ -208,7 +260,7 @@ ozi_route_disp(const waypoint * waypointp) if (waypointp->altitude == unknown_alt) { alt_feet = -777; } else { - alt_feet = (waypointp->altitude * 3.2808); + alt_feet = METERS_TO_FEET(waypointp->altitude); } /* @@ -232,7 +284,7 @@ ozi_route_disp(const waypoint * waypointp) * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 */ - fprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%.5f,0,1,3,0,65535,%s,0,0\r\n", + gbfprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%.5f,0,1,3,0,65535,%s,0,0\r\n", route_out_count, route_wpt_count, waypointp->shortname ? waypointp->shortname : "", @@ -257,7 +309,7 @@ ozi_route_pr() static void rd_init(const char *fname) { - file_in = xfopen(fname, "r", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); mkshort_handle = mkshort_new_handle(); } @@ -265,9 +317,9 @@ rd_init(const char *fname) static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); file_in = NULL; - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } static void @@ -286,10 +338,7 @@ wr_init(const char *fname) /* set mkshort options from the command line if applicable */ if (global_opts.synthesize_shortnames) { - if (snlenopt) - setshort_length(mkshort_handle, atoi(snlenopt)); - else - setshort_length(mkshort_handle, 32); + setshort_length(mkshort_handle, atoi(snlenopt)); if (snwhiteopt) setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); @@ -308,15 +357,18 @@ wr_init(const char *fname) static void wr_deinit(void) { - fclose(file_out); - file_out = NULL; + if (file_out != NULL) { + + gbfclose(file_out); + file_out = NULL; + } ozi_ofname = NULL; - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } static void -ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp) +ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp, ozi_fsdata *fsdata) { double alt; @@ -351,9 +403,11 @@ ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp) break; case 8: /* foreground color (0=black) */ + fsdata->fgcolor = atoi(str); break; case 9: /* background color (65535=yellow) */ + fsdata->bgcolor = atoi(str); break; case 10: /* Description */ @@ -367,6 +421,7 @@ ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp) break; case 13: /* proximity distance - meters */ + wpt_tmp->proximity = atof(str); break; case 14: /* altitude in feet */ @@ -374,7 +429,7 @@ ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp) if (alt == -777) { wpt_tmp->altitude = unknown_alt; } else { - wpt_tmp->altitude = alt * .3048; + wpt_tmp->altitude = FEET_TO_METERS(alt); } break; case 15: @@ -419,7 +474,7 @@ ozi_parse_track(int field, char *str, waypoint * wpt_tmp) if (alt == -777) { wpt_tmp->altitude = unknown_alt; } else { - wpt_tmp->altitude = alt * .3048; + wpt_tmp->altitude = FEET_TO_METERS(alt); } break; case 4: @@ -521,16 +576,14 @@ ozi_parse_routeheader(int field, char *str, waypoint * wpt_tmp) static void data_read(void) { - char buff[1024]; + char *buff; char *s; waypoint *wpt_tmp; int i; int linecount = 0; - - do { + + while ((buff = gbfgetstr(file_in))) { linecount++; - memset(buff, '\0', sizeof(buff)); - fgets(buff, sizeof(buff), file_in); /* * this is particularly nasty. use the first line of the file @@ -556,7 +609,7 @@ data_read(void) } if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { - + ozi_fsdata *fsdata = ozi_alloc_fsdata(); wpt_tmp = waypt_new(); /* data delimited by commas, possibly enclosed in quotes. */ @@ -578,8 +631,11 @@ data_read(void) break; case wptdata: - ozi_parse_waypt(i, s, wpt_tmp); + ozi_parse_waypt(i, s, wpt_tmp, fsdata); break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; } i++; s = csv_lineparse(NULL, ",", "", linecount); @@ -588,7 +644,7 @@ data_read(void) switch (ozi_objective) { case trkdata: if (linecount > 6) /* skipping over file header */ - route_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); else waypt_free(wpt_tmp); break; @@ -599,18 +655,24 @@ data_read(void) waypt_free(wpt_tmp); break; case wptdata: - if (linecount > 4) /* skipping over file header */ + if (linecount > 4) { /* skipping over file header */ + fs_chain_add(&(wpt_tmp->fs), + (format_specific_data *) fsdata); waypt_add(wpt_tmp); - else + } else { waypt_free(wpt_tmp); + } break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; } } else { /* empty line */ } - } while (!feof(file_in)); + } } static void @@ -621,13 +683,22 @@ ozi_waypt_pr(const waypoint * wpt) double ozi_time; char *description; char *shortname; + int faked_fsdata = 0; + ozi_fsdata *fs = NULL; + + fs = (ozi_fsdata *) fs_chain_find(wpt->fs, FS_OZI); + + if (!fs) { + fs = ozi_alloc_fsdata(); + faked_fsdata = 1; + } ozi_time = (wpt->creation_time / 86400.0) + 25569.0; if (wpt->altitude == unknown_alt) { alt_feet = -777; } else { - alt_feet = (wpt->altitude * 3.2808); + alt_feet = METERS_TO_FEET(wpt->altitude); } if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) { @@ -635,35 +706,43 @@ ozi_waypt_pr(const waypoint * wpt) if (global_opts.synthesize_shortnames) shortname = mkshort_from_wpt(mkshort_handle, wpt); else - shortname = csv_stringclean(wpt->description, ","); + shortname = csv_stringclean(wpt->description, BADCHARS); } else { /* no description available */ shortname = xstrdup(""); } } else { - shortname = csv_stringclean(wpt->shortname, ","); + shortname = csv_stringclean(wpt->shortname, BADCHARS); } if (!wpt->description) { if (shortname) { - description = csv_stringclean(shortname, ","); + description = csv_stringclean(shortname, BADCHARS); } else { description = xstrdup(""); } } else { - description = csv_stringclean(wpt->description, ","); + description = csv_stringclean(wpt->description, BADCHARS); } index++; - fprintf(file_out, - "%d,%s,%.6f,%.6f,%.5f,%d,%d,%d,%d,%d,%s,%d,%d,%d,%.0f,%d,%d,%d\r\n", + gbfprintf(file_out, + "%d,%s,%.6f,%.6f,%.5f,%d,%d,%d,%d,%d,%s,%d,%d,", index, shortname, wpt->latitude, wpt->longitude, ozi_time, 0, - 1, 3, 0, 65535, description, 0, 0, 0, alt_feet, 6, 0, 17); + 1, 3, fs->fgcolor, fs->bgcolor, description, 0, 0); + if (wpt->proximity > 0) + gbfprintf(file_out, "%.1f,", wpt->proximity); + else + gbfprintf(file_out,"0,"); + gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt_feet, 6, 0, 17); xfree(description); xfree(shortname); + if (faked_fsdata) { + xfree(fs); + } } static void @@ -680,7 +759,7 @@ data_write(void) if (waypt_count()) { ozi_objective = wptdata; ozi_openfile(ozi_ofname); - fprintf(file_out, ozi_wpt_header); + gbfprintf(file_out, ozi_wpt_header); waypt_disp_all(ozi_waypt_pr); } @@ -707,5 +786,6 @@ ff_vecs_t ozi_vecs = { data_read, data_write, NULL, - ozi_args + ozi_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/palmdoc.c b/palmdoc.c index 8a5054645..aa5d401e6 100644 --- a/palmdoc.c +++ b/palmdoc.c @@ -23,14 +23,15 @@ #include "defs.h" +#if PDBFMTS_ENABLED #include "jeeps/gpsmath.h" #include #include "coldsync/palm.h" #include "coldsync/pdb.h" static FILE *file_out; -static void *mkshort_handle; -static void *mkshort_bookmark_handle; +static short_handle mkshort_handle; +static short_handle mkshort_bookmark_handle; static const char *out_fname; static struct pdb *opdb; static struct pdb_record *opdb_rec; @@ -43,7 +44,7 @@ static char *includelogs = NULL; static int ct = 1; static int offset = 0; -static char *encrypt; +static char *palm_encrypt; #define MYNAME "PALMDOC" @@ -67,29 +68,29 @@ struct buffer { static arglist_t palmdoc_args[] = { { "nosep", &suppresssep, - "Suppress separator lines between waypoints", NULL, - ARGTYPE_BOOL }, - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING }, - {"encrypt", &encrypt, "Encrypt hints with ROT13", NULL, - ARGTYPE_BOOL }, + "No separator lines between waypoints", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"encrypt", &palm_encrypt, "Encrypt hints with ROT13", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX }, { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL }, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, { "bookmarks_short", &bmid, "Include short name in bookmarks", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static struct buffer buf; struct doc_record0 /* 16 bytes total */ { - unsigned short version; /* 1 = plain text, 2 = compressed */ - unsigned short reserved1; - unsigned long doc_size; /* in bytes, when uncompressed */ - unsigned short num_records; /* PDB header numRecords - 1 */ - unsigned short rec_size; /* usually RECORD_SIZE_MAX */ - unsigned long reserved2; - unsigned short recsizes[1]; + gbuint16 version; /* 1 = plain text, 2 = compressed */ + gbuint16 reserved1; + gbuint32 doc_size; /* in bytes, when uncompressed */ + gbuint16 num_records; /* PDB header numRecords - 1 */ + gbuint16 rec_size; /* usually RECORD_SIZE_MAX */ + gbuint32 reserved2; + gbuint16 recsizes[1]; }; static struct recordsize { @@ -105,7 +106,7 @@ static struct bookmark { struct bookmark_record { char text[16]; - unsigned long offset; + gbuint32 offset; }; static void put_byte(struct buffer *b, unsigned char c, int *space) @@ -142,7 +143,7 @@ static unsigned char * mem_find(unsigned char *t, int t_len, unsigned char *m, i } -static void compress( struct buffer *b ) +static void pd_compress( struct buffer *b ) { unsigned i, j; @@ -315,7 +316,7 @@ static void commit_buffer( void ) { newrec->size = buf.len; recordsize_tail = newrec; - compress( &buf ); + pd_compress( &buf ); opdb_rec = new_Record (0, 0, ct++, (uword) buf.len, (const ubyte *)buf.data); @@ -400,8 +401,8 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); - mkshort_del_handle(mkshort_bookmark_handle); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_bookmark_handle); if ( dbname ) { xfree(dbname); @@ -448,7 +449,7 @@ palmdoc_disp(const waypoint *wpt) tm = time(NULL); strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%ld%c %6.0f %7.0f)", + docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%d%c %6.0f %7.0f)", (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint), @@ -460,6 +461,10 @@ palmdoc_disp(const waypoint *wpt) docprintf(10+strlen(wpt->description), "%s\n", wpt->description); } if (wpt->gc_data.terr) { + + docprintf (100, "%s/%s\n", gs_get_cachetype(wpt->gc_data.type), + gs_get_container(wpt->gc_data.container)); + if (wpt->gc_data.desc_short.utfstring) { char *stripped_html = strip_html(&wpt->gc_data.desc_short); docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); @@ -472,7 +477,7 @@ palmdoc_disp(const waypoint *wpt) } if (wpt->gc_data.hint) { char *hint = NULL; - if ( encrypt ) + if ( palm_encrypt ) hint = rot13( wpt->gc_data.hint ); else hint = xstrdup( wpt->gc_data.hint ); @@ -557,7 +562,7 @@ palmdoc_disp(const waypoint *wpt) encstr = xml_attribute( logpart, "encoded" ); encoded = (encstr[0] != 'F'); - if ( encrypt && encoded ) { + if ( palm_encrypt && encoded ) { s = rot13( logpart->cdata ); } else { @@ -623,7 +628,9 @@ ff_vecs_t palmdoc_vecs = { NULL, data_write, NULL, - palmdoc_args + palmdoc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/pathaway.c b/pathaway.c index ab85b0cf2..231b7a329 100644 --- a/pathaway.c +++ b/pathaway.c @@ -1,6 +1,6 @@ /* Support for PathAway Palm Database, - Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de + Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,13 +24,17 @@ The german release 3.0 of PathAway violates the PathAway standards: * N.. .... O.. .... instead of N.. .... E.. .... * date is formatted in DDMMYYYY instead of YYYYMMDD + + Release 4.x store only numeric coordinates and uses a six-number date. */ #include #include "defs.h" +#if PDBFMTS_ENABLED #include "coldsync/palm.h" #include "coldsync/pdb.h" #include "csv_util.h" +#include "strptime.h" #define MYNAME "pathaway" @@ -38,12 +42,13 @@ #define PPDB_MAGIC_WPT 0x506f4c69 /* PoLi */ #define PPDB_MAGIC 0x4b6e5772 /* KwNr */ -FILE *fd_in, *fd_out; -struct pdb *pdb_in, *pdb_out; -char *fname_in, *fname_out; -static void *mkshort_handle; +static FILE *fd_in, *fd_out; +static struct pdb *pdb_in, *pdb_out; +static char *fname_in, *fname_out; +static short_handle mkshort_handle; static gpsdata_type ppdb_type; -unsigned char german_release = 0; +static unsigned char german_release = 0; +static char *datefmt; typedef struct ppdb_appdata { @@ -57,24 +62,21 @@ typedef struct ppdb_appdata #define PPDB_APPINFO_SIZE sizeof(struct ppdb_appdata) -static char *dbname = NULL; -static char *deficon = NULL; -static char *snlen_opt = NULL; +static char *opt_dbname = NULL; +static char *opt_deficon = NULL; +static char *opt_snlen = NULL; +static char *opt_date = NULL; static arglist_t ppdb_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING}, - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING}, - {"snlen", &snlen_opt, "Length of generated shortnames", NULL, ARGTYPE_INT }, - {0, 0, 0, 0, 0 } + {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; -static void -is_fatal(int is, const char *msg, ... ) -{ - if (is) fatal(MYNAME ": %s\n", msg); -} - +/*#undef PPDB_DEBUG*/ #define PPDB_DEBUG 1 #if PPDB_DEBUG @@ -94,13 +96,13 @@ internal_debug2(const char *format, ... ) puts(""); va_end(args); } -#define DBG internal_debug1(__FILE__, __LINE__);internal_debug2 +#define DBG(args) internal_debug1(__FILE__, __LINE__);internal_debug2 args #else -#define DBG # ; +#define DBG(args) ; #endif -#define CHECK_INP(i, j) is_fatal((i != j), "Error in data structure.") +#define CHECK_INP(i, j, k) is_fatal((i != j), "Error in data structure (%s).", (k)) /* * utilities @@ -231,17 +233,9 @@ char *ppdb_fmt_degrees(char dir, double val) char *str = str_pool_get(32); int deg = fabs(val); double min = 60.0 * (fabs(val) - deg); - int power = 0; - double fx = min; char *tmp; - while (fx > 1.0) - { - fx = fx / 10.0; - power++; - } - snprintf(str, 31, "%c%02d 000", dir, deg); - snprintf(str + 6 - power, 24, "%.8f", min); + snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); tmp = str + strlen(str) - 1; /* trim trailing nulls */ while ((tmp > str) && (*tmp == '0')) @@ -267,7 +261,7 @@ double ppdb_decode_coord(const char *str) if (*str < 'A') /* only numeric */ { - CHECK_INP(1, sscanf(str,"%lf", &val)); + CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1)"); return val; } else @@ -279,12 +273,12 @@ double ppdb_decode_coord(const char *str) tmp = strchr(str, ' '); if ((tmp) && (tmp - str < 4)) { - CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val)); + CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val), "decode_coord(2)"); val = deg + (val / 60.0); } else { - CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val)); + CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3)"); } if ((dir == 'S') || (dir == 'W')) val = -val; @@ -296,55 +290,86 @@ static int ppdb_decode_tm(char *str, struct tm *tm) { int msec, d1, d2, d3, d4; - time_t tnow; - struct tm now; int year; + char *cx; if (*str == '\0') return 0; /* empty date and time */ if (strchr(str, '.')) /* time in hhmmss.ms */ { - CHECK_INP(8, sscanf(str, "%02d%02d%02d.%d %02d%02d%02d%02d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec, - &msec, &d1, &d2, &d3, &d4)); + CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), + "decode_tm(1)"); } else { - CHECK_INP(7, sscanf(str, "%02d%02d%02d %02d%02d%02d%02d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec, - &d1, &d2, &d3, &d4)); + CHECK_INP(3, sscanf(str, "%02d%02d%02d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec), + "decode_tm(2)"); } - - tnow = current_time(); - now = *localtime(&tnow); - now.tm_year += 1900; - now.tm_mon++; + cx = strchr(str, ' '); + if (cx == NULL) return 0; /* no date */ - year = (d1 * 100) + d2; + while (*cx == ' ') cx++; + if (*cx == '\0') return 0; /* no date */ - /* the coordinates comes before date and time in - the dataset, so the flag "german_release" is set yet. */ - - /* next code works for most, except for 19. and 20. of month */ - - if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYY ????? */ + if (datefmt) { - tm->tm_year = (d3 * 100) + d4; - tm->tm_mon = d2; - tm->tm_mday = d1; + struct tm tm2; + + if (NULL == strptime(cx, datefmt, &tm2)) + { + fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); + } + + tm->tm_year = tm2.tm_year + 1900; + tm->tm_mon = tm2.tm_mon + 1; + tm->tm_mday = tm2.tm_mday; } else { - tm->tm_year = (d1 * 100) + d2; - tm->tm_mon = d3; - tm->tm_mday = d4; - } + time_t tnow; + struct tm now; + + if (strlen(cx) != 8) + { + printf(MYNAME ": Date from first record is %s.\n", cx); + printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); + fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); + } + + CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3)"); + + tnow = current_time(); + now = *localtime(&tnow); + now.tm_year += 1900; + now.tm_mon++; + + year = (d1 * 100) + d2; + + /* the coordinates comes before date and time in + the dataset, so the flag "german_release" is set yet. */ + /* next code works for most, except for 19. and 20. of month */ + + if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYY ????? */ + { + tm->tm_year = (d3 * 100) + d4; + tm->tm_mon = d2; + tm->tm_mday = d1; + } + else + { + tm->tm_year = (d1 * 100) + d2; + tm->tm_mon = d3; + tm->tm_mday = d4; + } + } return 1; } static -int ppdb_read_wpt(const struct pdb *pdb_in, const struct pdb_record *pdb_rec, route_head *head) +int ppdb_read_wpt(const struct pdb *pdb_in, const struct pdb_record *pdb_rec, route_head *head, int isRoute) { char *data, *str; double altfeet; @@ -371,9 +396,9 @@ int ppdb_read_wpt(const struct pdb *pdb_in, const struct pdb_record *pdb_rec, ro case 3: if (*str != '\0') { - CHECK_INP(1, sscanf(str, "%lf", &altfeet)); + CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude"); if (altfeet != -9999) - wpt_tmp->altitude = altfeet / 3.2808; + wpt_tmp->altitude = FEET_TO_METERS(altfeet); } break; case 4: @@ -400,8 +425,10 @@ int ppdb_read_wpt(const struct pdb *pdb_in, const struct pdb_record *pdb_rec, ro str = csv_lineparse(NULL, ",", """", line++); } - if (head) + if (head && isRoute ) route_add_wpt(head, wpt_tmp); + else if (head) + track_add_wpt(head, wpt_tmp); else waypt_add(wpt_tmp); @@ -419,6 +446,10 @@ static void ppdb_rd_init(const char *fname) str_pool_init(); fd_in = xfopen(fname, "rb", MYNAME); + if (opt_date) + datefmt = convert_human_date_format(opt_date); + else + datefmt = NULL; } static void ppdb_rd_deinit(void) @@ -426,6 +457,7 @@ static void ppdb_rd_deinit(void) fclose(fd_in); str_pool_deinit(); xfree(fname_in); + if (datefmt) xfree(datefmt); } static void ppdb_read(void) @@ -449,7 +481,6 @@ static void ppdb_read(void) info = (ppdb_appdata_t *) pdb_in->appinfo; descr = info->vehicleStr; } - switch(pdb_in->type) { case PPDB_MAGIC_TRK: @@ -484,16 +515,19 @@ static void ppdb_read(void) track_head = route_head_alloc(); track_add_head(track_head); track_head->rte_name = xstrdup(pdb_in->name); - ppdb_read_wpt(pdb_in, pdb_rec, track_head); + ppdb_read_wpt(pdb_in, pdb_rec, track_head, 0); break; case rtedata: route_head = route_head_alloc(); route_add_head(route_head); route_head->rte_name = xstrdup(pdb_in->name); - ppdb_read_wpt(pdb_in, pdb_rec, route_head); + ppdb_read_wpt(pdb_in, pdb_rec, route_head, 1); break; case wptdata: - ppdb_read_wpt(pdb_in, pdb_rec, NULL); + ppdb_read_wpt(pdb_in, pdb_rec, NULL, 0); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); break; } @@ -515,23 +549,29 @@ static void ppdb_wr_init(const char *fname) if (global_opts.synthesize_shortnames != 0) { - if (snlen_opt != NULL) - len = atoi(snlen_opt); - else - len = 10; + len = atoi(opt_snlen); setshort_length(mkshort_handle, len); setshort_mustupper(mkshort_handle, 1); setshort_badchars(mkshort_handle, ","); setshort_whitespace_ok(mkshort_handle, 0); } + if (opt_date) + { + char *c = convert_human_date_format(opt_date); + xasprintf(&datefmt, "%s %s", "%H%M%S", c); + xfree(c); + } + else + datefmt = xstrdup("%H%M%S %Y%m%d"); } static void ppdb_wr_deinit(void) { - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); fclose(fd_out); str_pool_deinit(); xfree(fname_out); + if (datefmt) xfree(datefmt); } /* @@ -570,7 +610,7 @@ static void ppdb_write_wpt(const waypoint *wpt) if (fabs(wpt->altitude) < 9999.0) { tmp = str_pool_get(32); - snprintf(tmp, 32, ppdb_fmt_float(wpt->altitude * 3.2808)); + snprintf(tmp, 32, ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); buff = ppdb_strcat(buff, tmp, NULL, &len); } buff = ppdb_strcat(buff, ",", NULL, &len); @@ -578,7 +618,7 @@ static void ppdb_write_wpt(const waypoint *wpt) { tmp = str_pool_get(20); tm = *gmtime(&wpt->creation_time); - strftime(tmp, 20, "%H%M%S %Y%m%d", &tm); + strftime(tmp, 20, datefmt, &tm); buff = ppdb_strcat(buff, tmp, NULL, &len); } buff = ppdb_strcat(buff, ",", NULL, &len); @@ -586,7 +626,7 @@ static void ppdb_write_wpt(const waypoint *wpt) if (global_opts.synthesize_shortnames != 0) { tmp = mkshort_from_wpt(mkshort_handle, wpt); - DBG("shortname %s from %s", tmp, wpt->shortname); + DBG(("shortname %s from %s", tmp, wpt->shortname)); } else { @@ -597,7 +637,7 @@ static void ppdb_write_wpt(const waypoint *wpt) buff = ppdb_strcat(buff, tmp, "", &len); buff = ppdb_strcat(buff, ",", NULL, &len); - buff = ppdb_strcat(buff, deficon, "0", &len); + buff = ppdb_strcat(buff, opt_deficon, "0", &len); buff = ppdb_strcat(buff, ",", NULL, &len); tmp = str_pool_getcpy(wpt->description, ""); @@ -643,8 +683,8 @@ static void ppdb_write(void) if (NULL == (pdb_out = new_pdb())) fatal(MYNAME ": new_pdb failed\n"); - if (dbname) - strncpy(pdb_out->name, dbname, PDB_DBNAMELEN); + if (opt_dbname) + strncpy(pdb_out->name, opt_dbname, PDB_DBNAMELEN); pdb_out->name[PDB_DBNAMELEN-1] = 0; pdb_out->attributes = PDB_ATTR_BACKUP; @@ -663,22 +703,25 @@ static void ppdb_write(void) switch(global_opts.objective) /* Only one target is possible */ { case wptdata: - if (dbname == NULL) strncpy(pdb_out->name, "PathAway Waypoints", PDB_DBNAMELEN); + if (opt_dbname == NULL) strncpy(pdb_out->name, "PathAway Waypoints", PDB_DBNAMELEN); pdb_out->type = PPDB_MAGIC_WPT; waypt_disp_all(ppdb_write_wpt); break; case trkdata: - if (dbname == NULL) strncpy(pdb_out->name, "PathAway Track", PDB_DBNAMELEN); + if (opt_dbname == NULL) strncpy(pdb_out->name, "PathAway Track", PDB_DBNAMELEN); pdb_out->type = PPDB_MAGIC_TRK; appinfo->dataBaseSubType = 0; track_disp_all(ppdb_track_header, ppdb_track_trailer, ppdb_write_wpt); break; case rtedata: - if (dbname == NULL) strncpy(pdb_out->name, "PathAway Route", PDB_DBNAMELEN); + if (opt_dbname == NULL) strncpy(pdb_out->name, "PathAway Route", PDB_DBNAMELEN); pdb_out->type = PPDB_MAGIC_TRK; appinfo->dataBaseSubType = 1; route_disp_all(ppdb_track_header, ppdb_track_trailer, ppdb_write_wpt); break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; } pdb_Write(pdb_out, fileno(fd_out)); @@ -697,5 +740,7 @@ ff_vecs_t ppdb_vecs = { ppdb_read, ppdb_write, NULL, - ppdb_args + ppdb_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/pcx.c b/pcx.c index 1bafae196..b6c33d66d 100644 --- a/pcx.c +++ b/pcx.c @@ -1,7 +1,8 @@ /* Access to Garmin PCX5 files. + Format described in: http://www.garmin.com/manuals/PCX5_OwnersManual.pdf - Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,44 +24,52 @@ #include "garmin_tables.h" #include -static FILE *file_in; -static FILE *file_out; -static void *mkshort_handle; +static gbfile *file_in, *file_out; +static short_handle mkshort_handle; +static short_handle mkshort_handle2; /* for track and route names */ static char *deficon = NULL; +static char *cartoexploreur; +static int read_as_degrees; +static int route_ctr; #define MYNAME "PCX" static arglist_t pcx_args[] = { {"deficon", &deficon, "Default icon name", "Waypoint", - ARGTYPE_STRING }, - {0, 0, 0, 0, 0} + ARGTYPE_STRING, ARG_NOMINMAX }, + {"cartoexploreur", &cartoexploreur, + "Write tracks compatible with Carto Exploreur", "", + ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = xfopen(fname, "r", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } static void rd_deinit(void) { - fclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = xfopen(fname, "w", MYNAME); + file_out = gbfopen(fname, "w", MYNAME); mkshort_handle = mkshort_new_handle(); + mkshort_handle2 = mkshort_new_handle(); } static void wr_deinit(void) { - fclose(file_out); - mkshort_del_handle(mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle2); } static void @@ -75,35 +84,59 @@ data_read(void) char time[9]; char month[4]; waypoint *wpt_tmp; - char ibuf[122]; + char *buff; struct tm tm; - route_head *track_head = NULL; + route_head *track = NULL; + route_head *route = NULL; int n; char lathemi, lonhemi; + read_as_degrees = 0; - for(;fgets(ibuf, sizeof(ibuf), file_in);) { + while ((buff = gbfgetstr(file_in))) + { + char *ibuf = lrtrim(buff); + char *cp; + switch (ibuf[0]) { case 'W': sscanf(ibuf, "W %6c %c%lf %c%lf %s %s %ld", name, &latdir, &lat, &londir, &lon, date, time, &alt); + if (alt == -9999) { + alt = unknown_alt; + } sscanf(&ibuf[60], "%40c", desc); + symnum = 18; sscanf(&ibuf[116], "%d", &symnum); desc[sizeof(desc)-1] = '\0'; name[sizeof(name)-1] = '\0'; + wpt_tmp = waypt_new(); wpt_tmp->altitude = alt; - wpt_tmp->shortname = xstrdup(name); - wpt_tmp->description = xstrdup(desc); - wpt_tmp->icon_descr = mps_find_desc_from_icon_number(symnum, PCX); + cp = lrtrim(name); + if (*cp != '\0') { + wpt_tmp->shortname = xstrdup(cp); + } + cp = lrtrim(desc); + if (*cp != '\0') { + wpt_tmp->description = xstrdup(cp); + } + wpt_tmp->icon_descr = gt_find_desc_from_icon_number(symnum, PCX, NULL); if (latdir == 'S') lat = -lat; if (londir == 'W') lon = -lon; - wpt_tmp->longitude = ddmm2degrees(lon); - wpt_tmp->latitude = ddmm2degrees(lat); + if (read_as_degrees) { + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + if (route != NULL) + route_add_wpt(route, waypt_dupe(wpt_tmp)); waypt_add(wpt_tmp); break; case 'H': @@ -113,15 +146,22 @@ data_read(void) H(2 chars)TN(tracknane\0) */ if (ibuf[3] == 'L' && ibuf[4] == 'A') { - track_head = route_head_alloc(); - track_head->rte_name = strdup("track"); - track_add_head(track_head); + track = route_head_alloc(); + track->rte_name = xstrdup("track"); + track_add_head(track); } else if (ibuf[3] == 'T' && ibuf[4] == 'N') { - track_head = route_head_alloc(); - track_head->rte_name = strdup(&ibuf[6]); - track_add_head(track_head); + track = route_head_alloc(); + track->rte_name = xstrdup(&ibuf[6]); + track_add_head(track); } break; + case 'R': + n = 1; + while (ibuf[n] == ' ') n++; + route = route_head_alloc(); + route->rte_name = xstrdup(&ibuf[n]); + route_add_head(route); + break; case 'T': n = sscanf(ibuf, "T %lf %lf %s %s %ld", &lat, &lon, date, time, &alt); @@ -147,19 +187,29 @@ data_read(void) strncpy(month, date+3, 3); month[3] = 0; tm.tm_mon = month_lookup(month); - tm.tm_year = atoi(date + 7) + 100; + tm.tm_year = atoi(date + 7); + if (tm.tm_year < 70) tm.tm_year += 100; wpt_tmp = waypt_new(); wpt_tmp->creation_time = mkgmtime(&tm); - wpt_tmp->latitude = lat; - wpt_tmp->longitude = lon; + if (read_as_degrees) { + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } wpt_tmp->altitude = alt; /* Did we get a track point before a track header? */ - if (track_head == NULL) { - track_head = route_head_alloc(); - track_head->rte_name = strdup("Default"); - track_add_head(track_head); + if (track == NULL) { + track = route_head_alloc(); + track->rte_name = xstrdup("Default"); + track_add_head(track); } - route_add_wpt(track_head, wpt_tmp); + track_add_wpt(track, wpt_tmp); + break; + case 'U': + read_as_degrees = ! strncmp("LAT LON DEG", ibuf + 3, 11); + break; default: ; } @@ -172,7 +222,6 @@ gpsutil_disp(const waypoint *wpt) double lon,lat; int icon_token = 0; char tbuf[1024]; - char *tp = tbuf; time_t tm = wpt->creation_time; lon = degrees2ddmm(wpt->longitude); @@ -181,18 +230,19 @@ gpsutil_disp(const waypoint *wpt) if (tm == 0) tm = current_time(); strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); - while (*tp) { - *tp = toupper(*tp); - tp++; - } - - icon_token = mps_find_icon_number_from_desc(wpt->icon_descr, PCX); - if (get_cache_icon(wpt)) { - icon_token = mps_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + strupper(tbuf); + + if (deficon) { + icon_token = atoi(deficon); + } else { + icon_token = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + if (get_cache_icon(wpt)) { + icon_token = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } } - fprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5d %-40.40s %5e %d\n", + gbfprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5d %-40.40s %5e %d\n", global_opts.synthesize_shortnames ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, @@ -202,7 +252,7 @@ gpsutil_disp(const waypoint *wpt) fabs(lon), tbuf, -9999, - wpt->description, + (wpt->description != NULL) ? wpt->description : "", 0.0, icon_token); } @@ -210,9 +260,40 @@ gpsutil_disp(const waypoint *wpt) static void pcx_track_hdr(const route_head *trk) { - fprintf(file_out, "\n\nH TN %s\n", trk->rte_name); - fprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT\n"); + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Trk%03d", route_ctr); + + name = mkshort(mkshort_handle2, (trk->rte_name != NULL) ? trk->rte_name : buff); + /* Carto Exploreur (popular in France) chokes on trackname headers, + * so provide option to supppress these. + */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nH TN %s\n", name); + } + xfree(name); + gbfprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT ;track\n"); +} +static void +pcx_route_hdr(const route_head *rte) +{ + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Rte%03d", route_ctr); + + name = mkshort(mkshort_handle2, (rte->rte_name != NULL) ? rte->rte_name : buff); + + /* see pcx_track_hdr */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nR %s\n", name); + } + gbfprintf(file_out, "\n" +"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); } void @@ -226,13 +307,13 @@ pcx_track_disp(const waypoint *wpt) lon = degrees2ddmm(wpt->longitude); lat = degrees2ddmm(wpt->latitude); - tm = localtime(&wpt->creation_time); + tm = gmtime(&wpt->creation_time); - strftime(tbuf, sizeof(tbuf), "%d-%b-%y %T", tm); + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %H:%M:%S", tm); /* currently ...%T does nothing under Windows */ for (tp = tbuf; *tp; tp++) { *tp = toupper(*tp); } - fprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", + gbfprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", lat < 0.0 ? 'S' : 'N', fabs(lat), lon < 0.0 ? 'W' : 'E', @@ -244,7 +325,7 @@ pcx_track_disp(const waypoint *wpt) static void data_write(void) { -fprintf(file_out, +gbfprintf(file_out, "H SOFTWARE NAME & VERSION\n" "I PCX5 2.09\n" "\n" @@ -252,21 +333,38 @@ fprintf(file_out, "M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" "\n" "H COORDINATE SYSTEM\n" -"U LAT LON DM\n" +"U LAT LON DM\n"); + + setshort_length(mkshort_handle, 6); + + setshort_length(mkshort_handle2, 20); /* for track and route names */ + setshort_whitespace_ok(mkshort_handle2, 0); + setshort_mustuniq(mkshort_handle2, 0); + + if (global_opts.objective == wptdata) + { + gbfprintf(file_out, "\n" "H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); - setshort_length(mkshort_handle, 6); - waypt_disp_all(gpsutil_disp); - if (global_opts.objective == trkdata) { + waypt_disp_all(gpsutil_disp); + } + else if (global_opts.objective == trkdata) + { + route_ctr = 0; track_disp_all(pcx_track_hdr, NULL, pcx_track_disp); } + else if (global_opts.objective == rtedata) + { + route_ctr = 0; + route_disp_all(pcx_route_hdr, NULL, gpsutil_disp); + } } ff_vecs_t pcx_vecs = { ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none }, + FF_CAP_RW_ALL, rd_init, wr_init, rd_deinit, @@ -274,5 +372,6 @@ ff_vecs_t pcx_vecs = { data_read, data_write, NULL, - pcx_args + pcx_args, + CET_CHARSET_ASCII, 1 /* CET-REVIEW */ }; diff --git a/polygon.c b/polygon.c index 174eec4c6..5f2abce18 100644 --- a/polygon.c +++ b/polygon.c @@ -19,14 +19,80 @@ */ #include "defs.h" +#include "filterdefs.h" +#if FILTERS_ENABLED #define MYNAME "Polygon filter" -extern queue waypt_head; - static char *polyfileopt = NULL; static char *exclopt = NULL; +/* + * This test for insideness is essentially an odd/even test. The + * traditional (simple) implementation of the odd/even test counts + * intersections along a test ray, and if it should happen to exactly hit + * a vertex of the polygon, it throws away the result and fires a different + * test ray. Since we're potentially testing hundreds of test points against + * a polygon with hundreds of sides, this seemed both wasteful and difficult + * to coordinate, so instead I added extra state to try to figure out what we + * would have seen if we had just missed the vertex. The result is the + * hodgepodge of "limbo" states explained below. On the credit side of the + * ledger, though, the tests for intersection are vastly simplified by always + * having a horizontal test ray. + * + * The general structure of this filter is: we loop over the points in the + * polygon. For each point, we update the state of each of the waypoints in + * the test set. Thus, the state of every waypoint is indeterminate until + * the end of the outer loop, at which point the state of every waypoint + * should theoretically be completely determined. + * + * The bits following this comment encode the current state of the test point + * as we go around the polygon. OUTSIDE clearly isn't a bit; it's just here + * for completeness. If it's not INSIDE, and it's not something else, it's + * clearly OUTSIDE. + * + * INSIDE is self-explanatory. What it means is that the last time we were + * certain of our state, we were inside of the polygon. + * + * LIMBO encodes a bit more state information, to handle the case where our + * test ray (a horizontal line) has intersected one of the vertices of the + * polygon exactly. If the two lines that meet at that vertex are on + * opposite sides of the test ray, it was an intersection. Otherwise, it just + * grazed a local minimum or maximum and so counted as either zero or two + * intersections - not a change in state. Horizontal lines encountered + * while in limbo don't change the limbo state. All other lines do. + * The rest of the bits talk about how we got into limbo, and thus what to do + * when we get out of limbo. + * + * LIMBO_UP means that the last line segment we saw going into limbo was + * headed upward. When we see another non-horizontal line segment, whether + * we flip the INSIDE bit or not depends on whether it also goes upward. If + * it does, we flip the INSIDE bit. Otherwise, we just clear our limbo state + * and go on as if nothing had happened. + * + * LIMBO_BEGIN means that the very first vertex in the polygon put us into a + * limbo state. We won't be able to resolve that limbo state until we get to + * the end of the cycle, and it can actually coexist with another more local + * limbo state. The next two bits talk about the beginning limbo state in + * more detail. + * + * BEGIN_UP means that the first non-horizontal line segment we encountered + * while in a LIMBO_BEGIN state went upward. As with LIMBO_UP, this is used + * to determine the final disposition of the limbo state when we get back + * around to the other end of the cycle. + * + * BEGIN_HOR is fairly temporary. It says that we've encountered one or more + * horizontal line segments at the beginning of the cycle, so we haven't yet + * been able to resolve the state of BEGIN_UP. It's a way of propagating the + * "firstness" forward until we can make a decision, without propagating it + * for every test point. + * + * UP is used to remember which way we were going in case we encounter a + * limbo state. + * + * -- RLP + */ + #define OUTSIDE 0 #define INSIDE 1 #define LIMBO 2 @@ -44,19 +110,19 @@ typedef struct { static arglist_t polygon_args[] = { {"file", &polyfileopt, "File containing vertices of polygon", - NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED }, + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, {"exclude", &exclopt, "Exclude points inside the polygon", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static void polytest ( double lat1, double lon1, double lat2, double lon2, - double lat3, double lon3, + double wlat, double wlon, unsigned short *state, int first, int last ) { - if ( lat1 == lat3 ) { - if ( lat2 < lat3 ) { + if ( lat1 == wlat ) { + if ( lat2 < wlat ) { /* going down */ if (*state & LIMBO) { if ( *state & LIMBO_UP ) { @@ -75,12 +141,12 @@ static void polytest ( double lat1, double lon1, *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; } } - else if ( first && (lon1 > lon3)) { + else if ( first && (lon1 > wlon)) { *state |= LIMBO_BEGIN; } } - else if ( lat2 == lat3 ) { - if ( first & (lon1 > lon3 || lon2 > lon3)) { + else if ( lat2 == wlat ) { + if ( first & (lon1 > wlon || lon2 > wlon)) { *state |= LIMBO_BEGIN | BEGIN_HOR; } else if (last && (*state & LIMBO_BEGIN) && (*state & LIMBO)) { @@ -94,9 +160,10 @@ static void polytest ( double lat1, double lon1, /* do nothing */ } else { - if ( lon1 <= lon3 && lon2 > lon3 ) { + if ( lon1 <= wlon && lon2 > wlon ) { if ( *state & UP ) { - *state = *state | LIMBO_UP & ~UP; + *state &= ~UP; + *state |= LIMBO_UP; } *state = *state | LIMBO; } @@ -112,7 +179,8 @@ static void polytest ( double lat1, double lon1, } else if (*state & LIMBO_BEGIN) { if ( *state & BEGIN_HOR ) { - *state = *state & ~BEGIN_HOR | BEGIN_UP; + *state &= ~BEGIN_HOR; + *state |= BEGIN_UP; } else if ( last ) { if ( !(*state & BEGIN_UP) ) { @@ -121,25 +189,25 @@ static void polytest ( double lat1, double lon1, *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; } } - else if ( first && (lon1 > lon3)) { + else if ( first && (lon1 > wlon)) { *state |= LIMBO_BEGIN | BEGIN_UP; } } *state = *state & ~UP; } - else if ( lat2 == lat3 ) { - if ( lat1 < lat3 ) { + else if ( lat2 == wlat ) { + if ( lat1 < wlat ) { if ( last ) { if ( *state & BEGIN_UP ) { *state = *state ^ INSIDE; } *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; } - else if ( lon2 > lon3 ) { + else if ( lon2 > wlon ) { *state |= LIMBO; } } - /* no case for lat1==lat3; that's above */ + /* no case for lat1==wlat; that's above */ else { if ( last ) { if ( !(*state & BEGIN_UP) ) { @@ -147,7 +215,7 @@ static void polytest ( double lat1, double lon1, } *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; } - else if ( lon2 > lon3 ) { + else if ( lon2 > wlon ) { *state |= LIMBO | LIMBO_UP; } else { @@ -156,16 +224,16 @@ static void polytest ( double lat1, double lon1, } } else { - if ( (lat1 > lat3 && lat2 < lat3) || - (lat1 < lat3 && lat2 > lat3)) { + if ( (lat1 > wlat && lat2 < wlat) || + (lat1 < wlat && lat2 > wlat)) { /* we only care if the lines might intersect */ - if ( lon1 > lon3 && lon2 > lon3 ) { + if ( lon1 > wlon && lon2 > wlon ) { *state = *state ^ INSIDE; } - else if (!(lon1 <= lon3 && lon2 <= lon3)) { + else if (!(lon1 <= wlon && lon2 <= wlon)) { /* we're inside the bbox of a diagonal line. math time. */ - double loni = lon1+(lon2-lon1)/(lat2-lat1)*(lat3-lat1); - if ( loni > lon3 ) { + double loni = lon1+(lon2-lon1)/(lat2-lat1)*(wlat-lat1); + if ( loni > wlon ) { *state = *state ^ INSIDE; } } @@ -187,17 +255,16 @@ polygon_process(void) int fileline = 0; int first = 1; int last = 0; + char *line; + gbfile *file_in; - FILE *polyfile = xfopen( polyfileopt, "r", MYNAME ); + file_in = gbfopen(polyfileopt, "r", MYNAME); olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL; - while ( !feof(polyfile)) { - char line[200]; + while ((line = gbfgetstr(file_in))) { char *pound = NULL; int argsfound = 0; - fgets( line, sizeof(line), polyfile ); - fileline++; pound = strchr( line, '#' ); @@ -260,9 +327,7 @@ polygon_process(void) lon1 = lon2; } } - - fclose(polyfile); - + gbfclose(file_in); QUEUE_FOR_EACH(&waypt_head, elem, tmp) { waypoint *wp = (waypoint *) elem; @@ -296,3 +361,4 @@ filter_vecs_t polygon_vecs = { NULL, polygon_args }; +#endif // FILTERS_ENABLED diff --git a/position.c b/position.c index 2df410826..d8177ad5c 100644 --- a/position.c +++ b/position.c @@ -19,26 +19,20 @@ */ #include "defs.h" +#include "filterdefs.h" #include "grtcirc.h" +#if FILTERS_ENABLED + #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -extern queue waypt_head; static route_head *cur_rte = NULL; static double pos_dist; static char *distopt = NULL; static char *purge_duplicates = NULL; -static char *latopt = NULL; -static char *lonopt = NULL; -static char *exclopt = NULL; -static char *nosort = NULL; -static char *maxctarg = NULL; -static int maxct; - -waypoint * home_pos; typedef struct { double distance; @@ -47,38 +41,21 @@ typedef struct { static arglist_t position_args[] = { {"distance", &distopt, "Maximum positional distance", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED }, + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, {"all", &purge_duplicates, "Suppress all points close to other points", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} -}; - -static -arglist_t radius_args[] = { - {"lat", &latopt, "Latitude for center point (D.DDDDD)", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED }, - {"lon", &lonopt, "Longitude for center point (D.DDDDD)", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED }, - {"distance", &distopt, "Maximum distance from center", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED }, - {"exclude", &exclopt, "Exclude points close to center", - NULL, ARGTYPE_BOOL }, - {"nosort", &nosort, "Inhibit sort by distance to center.", - NULL, ARGTYPE_BOOL }, - {"maxcount", &maxctarg,"Output no more than this number of points", - NULL, ARGTYPE_INT }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static double gc_distance(double lat1, double lon1, double lat2, double lon2) { return gcdist( - (lat1 * M_PI) / 180.0, - (lon1 * M_PI) / 180.0, - (lat2 * M_PI) / 180.0, - (lon2 * M_PI) / 180.0 + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) ); } @@ -111,22 +88,6 @@ position_comp(const void * a, const void * b) return(0); } -static int -dist_comp(const void * a, const void * b) -{ - const waypoint *x1 = *(waypoint **)a; - const waypoint *x2 = *(waypoint **)b; - extra_data *x1e = (extra_data *) x1->extra_data; - extra_data *x2e = (extra_data *) x2->extra_data; - - if (x1e->distance > x2e->distance) - return 1; - if (x1e->distance < x2e->distance) - return -1; - return 0; - -} - /* tear through a waypoint queue, processing points by distance */ static void position_runqueue(queue *q, int nelems, int qtype) @@ -156,7 +117,7 @@ position_runqueue(queue *q, int nelems, int qtype) comp[i]->longitude); /* convert radians to integer feet */ - dist = (int)(5280*tomiles(dist)); + dist = (int)(5280*radtomiles(dist)); if (dist <= pos_dist) { switch (qtype) { @@ -166,6 +127,9 @@ position_runqueue(queue *q, int nelems, int qtype) del = !!purge_duplicates; break; case trkdata: + track_del_wpt(cur_rte, comp[i]); + del = !!purge_duplicates; + break; case rtedata: route_del_wpt(cur_rte, comp[i]); del = !!purge_duplicates; @@ -174,34 +138,40 @@ position_runqueue(queue *q, int nelems, int qtype) break; } } - else if (del ) { - switch (qtype) { + else { + if (del ) { + switch (qtype) { case wptdata: - waypt_del(comp[i]); - waypt_free(comp[i]); + waypt_del(comp[j]); + waypt_free(comp[j]); del = 0; break; case trkdata: + track_del_wpt(cur_rte, comp[j]); + del = 0; + break; case rtedata: - route_del_wpt(cur_rte, comp[i]); + route_del_wpt(cur_rte, comp[j]); del = 0; break; default: break; + } } - } else { - j = i; /* advance last use point */ + j = i; } } if ( del ) { switch (qtype) { case wptdata: - waypt_del(comp[nelems-1]); - waypt_free(comp[nelems-1]); + waypt_del(comp[j]); + waypt_free(comp[j]); break; case trkdata: + track_del_wpt(cur_rte, comp[j]); + break; case rtedata: - route_del_wpt(cur_rte, comp[i]); + route_del_wpt(cur_rte, comp[j]); break; default: break; @@ -256,7 +226,7 @@ position_init(const char *args) { if ((*fm == 'm') || (*fm == 'M')) { /* distance is meters */ - pos_dist *= 3.2802; + pos_dist *= 3.2802; } } } @@ -265,118 +235,6 @@ void position_deinit(void) { } -void -radius_process(void) -{ - queue * elem, * tmp; - waypoint * waypointp; - double dist; - waypoint ** comp; - int i, wc; - queue temp_head; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - extra_data *ed; - - waypointp = (waypoint *)elem; - dist = gc_distance(waypointp->latitude, - waypointp->longitude, - home_pos->latitude, - home_pos->longitude); - - /* convert radians to float point statute miles */ - dist = tomiles(dist); - - if ((dist >= pos_dist) == (exclopt == NULL)) { - waypt_del(waypointp); - waypt_free(waypointp); - continue; - } - - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->distance = dist; - waypointp->extra_data = ed; - } - - wc = waypt_count(); - QUEUE_INIT(&temp_head); - - comp = (waypoint **) xcalloc(wc, sizeof(*comp)); - - i = 0; - - /* - * Create an array of remaining waypoints, popping them off the - * master queue as we go. This gives us something reasonable - * for qsort. - */ - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - comp[i] = wp; - waypt_del(wp); - i++; - } - - if (!nosort) { - qsort(comp, wc, sizeof(waypoint *), dist_comp); - } - - /* - * The comp array is now sorted by distance. As we run through it, - * we push them back onto the master wp list, letting us pass them - * on through in the modified order. - */ - for (i = 0; i < wc; i++) { - waypoint * wp = comp[i]; - - xfree(wp->extra_data); - wp->extra_data = NULL; - - if (maxctarg && i >= maxct) { - continue; - } - waypt_add(wp); - } - - xfree(comp); -} - -void -radius_init(const char *args) { - char *fm; - - pos_dist = 0; - - if (distopt) { - pos_dist = strtod(distopt, &fm); - - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to feet */ - pos_dist *= .6214; - } - } - - if (maxctarg) { - maxct = atoi(maxctarg); - } else { - maxct = 0; - } - - home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); - - if (latopt) - home_pos->latitude = atof(latopt); - if (lonopt) - home_pos->longitude = atof(lonopt); -} - -void -radius_deinit(void) { - if (home_pos) - xfree(home_pos); -} - filter_vecs_t position_vecs = { position_init, position_process, @@ -385,10 +243,4 @@ filter_vecs_t position_vecs = { position_args }; -filter_vecs_t radius_vecs = { - radius_init, - radius_process, - radius_deinit, - NULL, - radius_args -}; +#endif // FILTERS_ENABLED diff --git a/psitrex.c b/psitrex.c index 9c3da7da9..624433417 100644 --- a/psitrex.c +++ b/psitrex.c @@ -43,7 +43,7 @@ typedef struct psit_icon_mapping { static FILE *psit_file_in; static FILE *psit_file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; /* 2 = not written any tracks out 1 = change of track to write out track header @@ -57,8 +57,8 @@ char *snlen; static arglist_t psit_args[] = { /* {"snlen", &snlen, "Length of generated shortnames", - NULL, ARGTYPE_INT }, */ - {0, 0, 0, 0, 0} + NULL, ARGTYPE_INT, "1", NULL }, */ + ARG_TERMINATOR }; /* Taken from PsiTrex 1.13 */ @@ -208,7 +208,7 @@ psit_wr_deinit(void) static void psit_getToken(FILE *psit_file, char *buf, size_t sz, psit_tokenSep_type delimType) { - int c; + int c = -1; *buf = 0; @@ -313,7 +313,7 @@ psit_waypoint_r(FILE *psit_file, waypoint **wpt) /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); - thisWaypoint->icon_descr = mps_find_desc_from_icon_number(garmin_icon_num, PCX); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); waypt_add(thisWaypoint); @@ -347,10 +347,10 @@ psit_waypoint_w(FILE *psit_file, const waypoint *wpt) wpt->shortname; fprintf(psit_file, " %-6s, ", ident); - icon = mps_find_icon_number_from_desc(wpt->icon_descr, PCX); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { - icon = mps_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); } ident = psit_find_desc_from_icon_number(icon); @@ -434,7 +434,7 @@ psit_route_r(FILE *psit_file, route_head **rte) /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); - thisWaypoint->icon_descr = mps_find_desc_from_icon_number(garmin_icon_num, PCX); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); route_add_wpt(rte_head, thisWaypoint); @@ -458,7 +458,7 @@ psit_routehdr_w(FILE *psit_file, const route_head *rte) char *rname; waypoint *testwpt; - time_t uniqueValue; + time_t uniqueValue = 0; int allWptNameLengths; queue *elem, *tmp; @@ -482,7 +482,7 @@ psit_routehdr_w(FILE *psit_file, const route_head *rte) /* route name */ if (!rte->rte_name) { - sprintf(hdr, "Route%04x", uniqueValue); + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); rname = xstrdup(hdr); } else @@ -514,7 +514,7 @@ psit_track_r(FILE *psit_file, route_head **trk) struct tm tmTime; time_t dateTime = 0; - route_head *track_head; + route_head *track_head = NULL; unsigned int trk_count; waypoint *thisWaypoint; @@ -592,7 +592,7 @@ psit_track_r(FILE *psit_file, route_head **trk) thisWaypoint->creation_time = dateTime; thisWaypoint->centiseconds = 0; - route_add_wpt(track_head, thisWaypoint); + track_add_wpt(track_head, thisWaypoint); if (feof(psit_file)) break; @@ -613,7 +613,7 @@ psit_trackhdr_w(FILE *psit_file, const route_head *trk) unsigned int trk_datapoints; char *tname; waypoint *testwpt; - time_t uniqueValue; + time_t uniqueValue = 0; queue *elem, *tmp; @@ -635,7 +635,7 @@ psit_trackhdr_w(FILE *psit_file, const route_head *trk) /* track name */ if (!trk->rte_name) { - sprintf(hdr, "Track%04x", uniqueValue); + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); tname = xstrdup(hdr); } else @@ -780,7 +780,7 @@ psit_write(void) track_disp_all(psit_trackhdr_w_wrapper, psit_noop, psit_trackdatapoint_w_wrapper); } - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } @@ -794,5 +794,6 @@ ff_vecs_t psit_vecs = { psit_read, psit_write, NULL, - psit_args + psit_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/psp.c b/psp.c index b3a04e650..3970faaaf 100644 --- a/psp.c +++ b/psp.c @@ -21,7 +21,9 @@ */ #include "defs.h" +#include "cet_util.h" #include +#include "grtcirc.h" #define MYNAME "PSP" @@ -30,7 +32,7 @@ static FILE *psp_file_in; static FILE *psp_file_out; -static FILE *mkshort_handle; +static short_handle mkshort_handle; static int psp_fread(void *buff, size_t size, size_t members, FILE * fp) @@ -40,7 +42,8 @@ psp_fread(void *buff, size_t size, size_t members, FILE * fp) br = fread(buff, size, members, fp); if (br != members) { - fatal(MYNAME ": requested to read %d bytes, read %d bytes.\n", members, br); + fatal(MYNAME ": requested to read %ld bytes, read %ld bytes.\n", + (unsigned long) members, (unsigned long) br); } return (br); @@ -50,20 +53,15 @@ static double psp_fread_double(FILE *fp) { unsigned char buf[8]; - unsigned char sbuf[8]; - psp_fread(buf, 1, 8, fp); - le_read64(sbuf, buf); - return *(double *) sbuf; + return le_read_double(buf); } static void psp_fwrite_double(double x, FILE *fp) { - unsigned char *cptr = (unsigned char *)&x; unsigned char cbuf[8]; - - le_read64(cbuf, cptr); + le_write_double(cbuf,x); fwrite(cbuf, 8, 1, fp); } @@ -154,6 +152,7 @@ valid_psp_header(char * header) static char * buffer_washer(char * buff, int buffer_len) { +/* original code int i; for (i = 0 ; i < buffer_len - 1; i++) { @@ -164,6 +163,11 @@ buffer_washer(char * buff, int buffer_len) } } + return (buff); +*/ + char *c = cet_str_uni_to_any((const short *)buff, buffer_len >> 1, global_opts.charset); + strncpy(buff, c, buffer_len); + xfree(c); return (buff); } @@ -189,7 +193,7 @@ psp_wr_init(const char *fname) static void psp_wr_deinit(void) { - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); fclose(psp_file_out); } @@ -231,11 +235,11 @@ psp_read(void) /* 8 bytes - latitude in radians */ radians = psp_fread_double(psp_file_in); - lat = (radians * 180.0) / M_PI; + lat = DEG(radians); /* 8 bytes - longitude in radians */ radians = psp_fread_double(psp_file_in); - lon = (radians * 180.0) / M_PI; + lon = DEG(radians); /* since we don't know the origin of this PSP file, we use */ /* the grid byte adjust longitude, if necessary, mimicing */ @@ -349,8 +353,8 @@ psp_waypt_pr(const waypoint *wpt) } /* convert lat/long back to radians */ - lat = (wpt->latitude * M_PI) / 180.0; - lon = (wpt->longitude * M_PI) / 180.0; + lat = RAD(wpt->latitude); + lon = RAD(wpt->longitude); pindex++; le_write16(tbuf, pindex); @@ -466,5 +470,7 @@ ff_vecs_t psp_vecs = { psp_wr_deinit, psp_read, psp_write, - NULL + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/queue.c b/queue.c index db3c56e6e..1c0b54d65 100644 --- a/queue.c +++ b/queue.c @@ -20,6 +20,7 @@ */ #include "queue.h" +#include "stddef.h" void enqueue(queue *new_el, queue *old) @@ -40,3 +41,161 @@ dequeue(queue *element) prev->next = next; return element; } + +/* + * The following sorting code was derived from linked-list mergesort + * sample code by Simon Tatham, code obtained from: + * http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html + * Modified for use with gpsbabel's queues by Paul Fox, October 2006. + * + * Original description and copyright messages follow... + */ + +/* + * Demonstration code for sorting a linked list. + * + * The algorithm used is Mergesort, because that works really well + * on linked lists, without requiring the O(N) extra space it needs + * when you do it on arrays. + * + * ... + */ + +/* + * This file is copyright 2001 Simon Tatham. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +void +sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)) +{ + + queue *p, *q, *e, *tail, *oldhead, *list; + int insize, nmerges, psize, qsize, i; + + /* + * Special case: if `list' is empty, we're done. + */ + if (QUEUE_EMPTY(qh)) + return; + + /* + * The algorithm doesn't really want the extra list head + * element. So remove the list head for now. Put it back later. + */ + + list = QUEUE_FIRST(qh); + dequeue(qh); + + insize = 1; + + while (1) { + p = list; + oldhead = list; /* only used for circular linkage */ + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = (q->next == oldhead ? NULL : q->next); + if (!q) break; + } + + /* if q hasn't fallen off end, we have + * two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next element of + * merge comes from p or q + */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; q = q->next; qsize--; + if (q == oldhead) q = NULL; + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; p = p->next; psize--; + if (p == oldhead) p = NULL; + } else if (cmp(p,q) <= 0) { + /* First element of p is + * lower (or same); e must + * come from p. + */ + e = p; p = p->next; psize--; + if (p == oldhead) p = NULL; + } else { + /* First element of q is + * lower; e must come from + * q. + */ + e = q; q = q->next; qsize--; + if (q == oldhead) q = NULL; + } + + /* add the next element to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + + /* Maintain reverse pointers in a + * doubly linked list. */ + e->prev = tail; + + tail = e; + } + + /* now p has stepped `insize' places + * along, and q has too */ + p = q; + } + tail->next = list; + list->prev = tail; + + /* If we have done only one merge, we're finished. + * Allow for nmerges==0, the empty list case. + */ + if (nmerges <= 1) { + + /* Put the list head back at the start of the list */ + ENQUEUE_TAIL(list, qh); + return; + + } + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } +} diff --git a/queue.h b/queue.h index e042e235e..51250d1d8 100644 --- a/queue.h +++ b/queue.h @@ -1,7 +1,7 @@ /* Generic queueing utilities. - Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,11 +27,13 @@ typedef struct queue { void enqueue(queue *new_el, queue *old); queue * dequeue(queue *element); -#define QUEUE_INIT(head) (head)->next = (head)->prev = head -#define QUEUE_FIRST(head) (head)->next -#define QUEUE_NEXT(element) (element)->next -#define QUEUE_LAST(head) (head)->prev -#define QUEUE_EMPTY (head)->next == head +void sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)); + +#define QUEUE_INIT(head) (head)->next = ((head)->prev = head) +#define QUEUE_FIRST(head) ((head)->next) +#define QUEUE_NEXT(element) ((element)->next) +#define QUEUE_LAST(head) ((head)->prev) +#define QUEUE_EMPTY(head) ((head)->next == (head)) #define QUEUE_MOVE(newhead,oldhead) \ if ( (oldhead)->next == (oldhead) ) {\ (newhead)->next = (newhead)->prev = (newhead); \ diff --git a/quovadis.c b/quovadis.c index e71eda892..745c151ec 100644 --- a/quovadis.c +++ b/quovadis.c @@ -21,10 +21,11 @@ #include "quovadis.h" +#if PDBFMTS_ENABLED static FILE *file_in; static FILE *file_out; static const char *out_fname; -struct pdb *opdb; +static struct pdb *opdb; static int ct; static ubyte* rec_ptr = NULL; @@ -35,8 +36,8 @@ static char *dbname = NULL; static arglist_t quovadis_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING}, - {0, 0, 0, 0, 0} + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static struct qv_icon_mapping mapping[] = { @@ -197,8 +198,8 @@ quovadis_writewpt(waypoint *wpt) xfree(rec); if (rec_index == MAXRECORDS) { - fatal(MYNAME ": cannot store more than %d records at this time.\n", - MAXRECORDS); + fatal(MYNAME ": cannot store more than %lu records at this time.\n", + (unsigned long) MAXRECORDS); } } @@ -293,5 +294,7 @@ ff_vecs_t quovadis_vecs = { data_read, data_write, NULL, - quovadis_args + quovadis_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif diff --git a/radius.c b/radius.c new file mode 100644 index 000000000..831c4a8f4 --- /dev/null +++ b/radius.c @@ -0,0 +1,223 @@ +/* + Radius Filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "filterdefs.h" +#include "grtcirc.h" + +#if FILTERS_ENABLED + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +static double pos_dist; +static char *distopt = NULL; +static char *latopt = NULL; +static char *lonopt = NULL; +static char *exclopt = NULL; +static char *nosort = NULL; +static char *maxctarg = NULL; +static char *routename = NULL; +static int maxct; + +static waypoint * home_pos; + +typedef struct { + double distance; +} extra_data; + +static +arglist_t radius_args[] = { + {"lat", &latopt, "Latitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"lon", &lonopt, "Longitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"distance", &distopt, "Maximum distance from center", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, + {"exclude", &exclopt, "Exclude points close to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"nosort", &nosort, "Inhibit sort by distance to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"maxcount", &maxctarg,"Output no more than this number of points", + NULL, ARGTYPE_INT, "1", NULL }, + {"asroute", &routename,"Put resulting waypoints in route of this name", + NULL, ARGTYPE_STRING, NULL, NULL }, + ARG_TERMINATOR +}; + +static double +gc_distance(double lat1, double lon1, double lat2, double lon2) +{ + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); +} + +static int +dist_comp(const void * a, const void * b) +{ + const waypoint *x1 = *(waypoint **)a; + const waypoint *x2 = *(waypoint **)b; + extra_data *x1e = (extra_data *) x1->extra_data; + extra_data *x2e = (extra_data *) x2->extra_data; + + if (x1e->distance > x2e->distance) + return 1; + if (x1e->distance < x2e->distance) + return -1; + return 0; + +} + +void +radius_process(void) +{ + queue * elem, * tmp; + waypoint * waypointp; + double dist; + waypoint ** comp; + int i, wc; + queue temp_head; + route_head *rte_head = NULL; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + extra_data *ed; + + waypointp = (waypoint *)elem; + dist = gc_distance(waypointp->latitude, + waypointp->longitude, + home_pos->latitude, + home_pos->longitude); + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if ((dist >= pos_dist) == (exclopt == NULL)) { + waypt_del(waypointp); + waypt_free(waypointp); + continue; + } + + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->distance = dist; + waypointp->extra_data = ed; + } + + wc = waypt_count(); + QUEUE_INIT(&temp_head); + + comp = (waypoint **) xcalloc(wc, sizeof(*comp)); + + i = 0; + + /* + * Create an array of remaining waypoints, popping them off the + * master queue as we go. This gives us something reasonable + * for qsort. + */ + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + comp[i] = wp; + waypt_del(wp); + i++; + } + + if (!nosort) { + qsort(comp, wc, sizeof(waypoint *), dist_comp); + } + + if (routename) { + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(routename); + route_add_head(rte_head); + } + + /* + * The comp array is now sorted by distance. As we run through it, + * we push them back onto the master wp list, letting us pass them + * on through in the modified order. + */ + for (i = 0; i < wc; i++) { + waypoint * wp = comp[i]; + + xfree(wp->extra_data); + wp->extra_data = NULL; + + if (maxctarg && i >= maxct) { + continue; + } + if (routename) { + route_add_wpt(rte_head, wp); + } else { + waypt_add(wp); + } + } + + xfree(comp); +} + +void +radius_init(const char *args) { + char *fm; + + pos_dist = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } + + if (maxctarg) { + maxct = atoi(maxctarg); + } else { + maxct = 0; + } + + home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); + + if (latopt) + home_pos->latitude = atof(latopt); + if (lonopt) + home_pos->longitude = atof(lonopt); +} + +void +radius_deinit(void) { + if (home_pos) + xfree(home_pos); +} + +filter_vecs_t radius_vecs = { + radius_init, + radius_process, + radius_deinit, + NULL, + radius_args +}; +#endif // FILTERS_ENABLED diff --git a/reference/an1-an1.ref b/reference/an1-an1.ref index 17df313dda5810ea4d6ea27f5263b5f2669eec95..27ccc13efaf6b366b761189b2f637c27f948b1ac 100644 GIT binary patch delta 360 zcmeAZeicx&>MHY$4a*X^Fy%Uf)dk~y_gz)5fj0kc5$^1;nyap8BM-*NXGqTFd zC_EPyWVx*)c~ U1SS`A#Uq8#VoYlb91GbFzS$ zi&zpSOR|EQn^+SjYqEivhu9J(Te5?hm)H{~dvX+l%$@w0BYtuuC&c8>obi)0xe9?s h3QcC_jt9yEl?zQ4=7|SdTnMyOXtFYI{N$Ou-T;0dJBt7S diff --git a/reference/an1-out.ref b/reference/an1-out.ref index bcaff7772145afe3a433d5bc9627b06f7818497b..fb40144402ecf89bce435a5c230a3749374949c0 100644 GIT binary patch delta 158 zcmbQibc|_&ob0*(|No0HFfcGPG7%Q6vy9INRR`nRB`HQAdzsymO93*h%Z*`q&T4TDr*Vjh5+y3Niii~6uGb%Fv4g}MW@cw+ z-*4aly?HZbpJy331OVd#2o7T(9x^%AxXkJBZqXzpLL%Yt2^fjS!qHgdZJ45kX{#t1 zhx52S9Uj3xXnS1^z{{$hq=^d zGFs3b+NSb=s!LWhGJ;<|0R6>9HzAwoQ{n%F-fpA!xy#Ylkj}WErlzyu1F%zwEqmDH zbU*0MZySSI_xb>wDT%5^*``X)N-HNe7r41egq5!f9PLeqcX&rS2EAFFB+H!TbV@?3 zJWTwT%FQu1k;iFze9T|)yMK{;@u%0J0x!Z$&D71TN=)vQ)@0tcpJtm2)s;u9wYB<2 zPkfWN7j+W_pVv2~&V^v;v#XPstGZ!uVeIAvSIMf{PvPRWef*dY1OY`i>}-NRYXwyebg1 z=iP(Km#;xZRUl#Mwym#Aer$Vn4=dI@K4; zVzt3}S$hf2N}d&5qa|w2p{gjUFgY)U%he;?W zgAkt#2a>1WZz<3$PAwgRQg!9@_-0`{w7>`qk)pkER~tLhTJYKj?p-w9EeXQoXYL!}_m(eY + + + + + + 01 + Hohndorf + Hohndorf + City (Small) + + + + 0x9E + ž - latin small letter z with caron + ž - latin small letter z with caron + City (Small) + + + + 0xC9 + É - latin capital letter e with circumflex + É - latin capital letter e with circumflex + City (Small) + + + + 0xF0 + ð - latin small letter eth (icelandic) + ð - latin small letter eth (icelandic) + City (Small) + + + + CS + Ovládací, Prohlížení lokální síte + Ovládací, Prohlížení lokální síte + Waypoint + + + + DA + TÃ¥ning, netværkssøgning, áâãäåæéë + TÃ¥ning, netværkssøgning, áâãäåæéë + Waypoint + + + + DE + Himmelmühle, ä,ö,ü,Ä,Ö,Ü,ß + Himmelmühle, ä,ö,ü,Ä,Ö,Ü,ß + Waypoint + + + + EO + Trasercado de la loka ret + Trasercado de la loka ret + Waypoint + + + + ES + Matalascañas, Navegación, Táliga + Matalascañas, Navegación, Táliga + Waypoint + + + + FR + Boissière-École, Contrôle, réseau, Mâle + Boissière-École, Contrôle, réseau, Mâle + Waypoint + + + + HR + Pregledavanje lokalne mreže + Pregledavanje lokalne mreže + Waypoint + + + + HU + Hõgyész, Vezérlõközpont, Hálózat + Hõgyész, Vezérlõközpont, Hálózat + City (Small) + + + + IS + Borgarfjörður + Borgarfjörður + Waypoint + + + + SK + Ovládacie centrum + Ovládacie centrum + Waypoint + + + + X1 + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + Diamond, Blue + + + + X2 + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + žðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× + Diamond, Blue + + diff --git a/reference/cet/cet-sample.latin1.txt b/reference/cet/cet-sample.latin1.txt new file mode 100644 index 000000000..80efa7d23 --- /dev/null +++ b/reference/cet/cet-sample.latin1.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E $ - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 É - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovládací Prohlí$ení lokální síte 50.514406 13.638634 -99999999.00 255 1 +new DA Tåning netværkssøgning áâãäåæéë 56.011734 9.847870 -99999999.00 255 1 +new DE Himmelmühle äöüÄÖÜß 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalascañas Navegación Táliga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissière-École Contrôle réseau Mâle 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mre$e 50.477937 12.510391 -99999999.00 255 1 +new HU Hõgyész Vezérlõközpont Hálózat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjörður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovládacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 $ðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 +new X2 $ðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/cet/cet-sample.latin2.txt b/reference/cet/cet-sample.latin2.txt new file mode 100644 index 000000000..0db84c227 --- /dev/null +++ b/reference/cet/cet-sample.latin2.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E ¾ - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 É - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovládací Prohlí¾ení lokální síte 50.514406 13.638634 -99999999.00 255 1 +new DA Tåning netværkssøgning áâãäåæéë 56.011734 9.847870 -99999999.00 255 1 +new DE Himmelmühle äöüÄÖÜß 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalascañas Navegación Táliga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissière-École Contrôle réseau Mâle 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mre¾e 50.477937 12.510391 -99999999.00 255 1 +new HU Hõgyész Vezérlõközpont Hálózat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjörður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovládacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 ¾ðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 +new X2 ¾ðÉéÀàÈèÙùÂâÊêÎîÄäËëÖöÜüÆæÅ娸ÇçÑñ²³½É× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/cet/cet-sample.macroman.txt b/reference/cet/cet-sample.macroman.txt new file mode 100644 index 000000000..b41688788 --- /dev/null +++ b/reference/cet/cet-sample.macroman.txt @@ -0,0 +1,17 @@ +Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink +new 01 Hohndorf 50.738297 12.683029 -99999999.00 255 1 +new 0x9E $ - latin small letter z with caron 50.497971 13.027725 -99999999.00 255 1 +new 0xC9 ƒ - latin capital letter e with circumflex 50.497971 13.027725 -99999999.00 255 1 +new 0xF0 ð - latin small letter eth (icelandic) 50.497971 13.027725 -99999999.00 255 1 +new CS Ovl‡dac’ Prohl’$en’ lok‡ln’ s’te 50.514406 13.638634 -99999999.00 255 1 +new DA TŒning netv¾rkss¿gning ‡‰‹ŠŒ¾Ž‘ 56.011734 9.847870 -99999999.00 255 1 +new DE HimmelmŸhle ŠšŸ€…†§ 50.625865 13.060611 -99999999.00 255 1 +new EO Trasercado de la loka ret 50.495281 13.027645 -99999999.00 255 1 +new ES Matalasca–as Navegaci—n T‡liga 37.007446 -6.558838 -99999999.00 255 1 +new FR Boissire-ƒcole Contr™le rŽseau M‰le 48.679047 1.652069 -99999999.00 255 1 +new HR Pregledavanje lokalne mre$e 50.477937 12.510391 -99999999.00 255 1 +new HU H›gyŽsz VezŽrl›kšzpont H‡l—zat 46.491394 18.424072 -99999999.00 255 1 +new IS Borgarfjšrður 65.522461 -13.823547 -99999999.00 255 1 +new SK Ovl‡dacie centrum 50.724214 13.524871 -99999999.00 255 1 +new X1 $ðƒŽËˆéôå‰æë”€Šè‘…š†Ÿ®¾Œ¯¿‚„–²³½ƒ× 50.497971 13.027725 -99999999.00 255 1 +new X2 $ðƒŽËˆéôå‰æë”€Šè‘…š†Ÿ®¾Œ¯¿‚„–²³½ƒ× 50.497971 13.027725 -99999999.00 255 1 diff --git a/reference/coastexp.ref b/reference/coastexp.ref index 4c5dad94c..de4fac599 100644 --- a/reference/coastexp.ref +++ b/reference/coastexp.ref @@ -1,4 +1,4 @@ - + - + PESCDR01 diff --git a/reference/coastexp.ref3 b/reference/coastexp.ref3 index 9c32e3678..ae02d82d8 100644 --- a/reference/coastexp.ref3 +++ b/reference/coastexp.ref3 @@ -1,4 +1,4 @@ - + + + + + + 1400.000000 + F01140 + DECOLLO MONTE AVENA + DECOLLO MONTE AVENA + Waypoint + + + 300.000000 + F02030 + AVIOSUPERFICE FELTRE + AVIOSUPERFICE FELTRE + Waypoint + + + 230.000000 + F03023 + ATTERRAGGIO VALENTINE + ATTERRAGGIO VALENTINE + Waypoint + + + 320.000000 + F04032 + ATTERRAG. BIRRERIA PEDAVENA + ATTERRAG. BIRRERIA PEDAVENA + Waypoint + + + 420.000000 + F06042 + DIGA DEL MIS + DIGA DEL MIS + Waypoint + + + 460.000000 + F07046 + SOSPIROLO CHIESA + SOSPIROLO CHIESA + Waypoint + + + 450.000000 + F08045 + CESIOMAGGIORE FABBRICA + CESIOMAGGIORE FABBRICA + Waypoint + + + 290.000000 + F09029 + CARTIERA SGIUSTINA + CARTIERA SGIUSTINA + Waypoint + + + 380.000000 + F10038 + SEREN DEL GRAPPA CHIESA + SEREN DEL GRAPPA CHIESA + Waypoint + + + 346.900000 + F11031 + ARTEN FELTRE + ARTEN FELTRE + Waypoint + + + 450.000000 + F12045 + NORCEN CAMPI DA TENNIS + NORCEN CAMPI DA TENNIS + Waypoint + + + 380.000000 + F13038 + SOSPIROLO CAVA + SOSPIROLO CAVA + Waypoint + + + 1010.000000 + F14101 + COL MELON RIF BELVEDERE + COL MELON RIF BELVEDERE + Waypoint + + + 310.000000 + F15031 + FONZASO SPORTFUL + FONZASO SPORTFUL + Waypoint + + + 252.300000 + F16025 + BUSCHE LATTERIA + BUSCHE LATTERIA + Waypoint + + + 605.000000 + F17063 + LAMON + LAMON + Waypoint + + + 509.400000 + F18051 + ARSIE' + ARSIE' + Waypoint + + + 271.200000 + F19027 + CASTELLO DI FELTRE + CASTELLO DI FELTRE + Waypoint + + + 300.000000 + F20030 + SANTA LUCIA CHIESETTA + SANTA LUCIA CHIESETTA + Waypoint + + + 1430.000000 + F21143 + MALGA CAMPON + MALGA CAMPON + Waypoint + + + 300.000000 + F22030 + ZANUSSI MEL + ZANUSSI MEL + Waypoint + + + 270.000000 + F23027 + FELTRE OSPEDALE + FELTRE OSPEDALE + Waypoint + + + 860.000000 + F24086 + BAILO CASTEL TESINO + BAILO CASTEL TESINO + Waypoint + + + 450.000000 + F25045 + CASA SCEICCO + CASA SCEICCO + Waypoint + + diff --git a/reference/compegps.wpt b/reference/compegps.wpt new file mode 100644 index 000000000..722547566 --- /dev/null +++ b/reference/compegps.wpt @@ -0,0 +1,52 @@ +G WGS 84 +U 1 +W F01140 A 46.0294899313ºN 11.8258790855ºE 27-MAR-62 00:00:00 1400.000000 DECOLLO MONTE AVENA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F02030 A 46.0086266116ºN 11.8609316981ºE 27-MAR-62 00:00:00 300.000000 AVIOSUPERFICE FELTRE +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F03023 A 46.0211500041ºN 11.8854800796ºE 27-MAR-62 00:00:00 230.000000 ATTERRAGGIO VALENTINE +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F04032 A 46.0335865765ºN 11.8823672293ºE 27-MAR-62 00:00:00 320.000000 ATTERRAG. BIRRERIA PEDAVENA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F06042 A 46.1598476455ºN 12.0832581003ºE 27-MAR-62 00:00:00 420.000000 DIGA DEL MIS +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F07046 A 46.1441766659ºN 12.0754755514ºE 27-MAR-62 00:00:00 460.000000 SOSPIROLO CHIESA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F08045 A 46.0812815292ºN 11.9856990105ºE 27-MAR-62 00:00:00 450.000000 CESIOMAGGIORE FABBRICA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F09029 A 46.0755574914ºN 12.0333107491ºE 27-MAR-62 00:00:00 290.000000 CARTIERA SGIUSTINA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F10038 A 45.9885384730ºN 11.8450206880ºE 27-MAR-62 00:00:00 380.000000 SEREN DEL GRAPPA CHIESA +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F11031 A 46.0105131183ºN 11.8303758183ºE 27-MAR-62 00:00:00 346.900000 ARTEN FELTRE +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F12045 A 46.0478971020ºN 11.8738181282ºE 27-MAR-62 00:00:00 450.000000 NORCEN CAMPI DA TENNIS +w Waypoint,0,0.0,16777215,255,1,7,,10.0 +W F13038 A 46.1529066825ºN 12.1211567478ºE 27-MAR-62 00:00:00 380.000000 SOSPIROLO CAVA +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F14101 A 46.0427458323ºN 11.8523925232ºE 27-MAR-62 00:00:00 1010.000000 COL MELON RIF BELVEDERE +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F15031 A 46.0108797603ºN 11.8137179459ºE 27-MAR-62 00:00:00 310.000000 FONZASO SPORTFUL +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F16025 A 46.0406235353ºN 11.9840491129ºE 27-MAR-62 00:00:00 252.300000 BUSCHE LATTERIA +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F17063 A 46.0469308434ºN 11.7485280506ºE 27-MAR-62 00:00:00 605.000000 LAMON +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F18051 A 45.9916739281ºN 11.7463576240ºE 27-MAR-62 00:00:00 509.400000 ARSIE' +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F19027 A 46.0189789055ºN 11.9110897654ºE 27-MAR-62 00:00:00 271.200000 CASTELLO DI FELTRE +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F20030 A 46.0114906453ºN 11.8334226329ºE 27-MAR-62 00:00:00 300.000000 SANTA LUCIA CHIESETTA +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F21143 A 46.0399765040ºN 11.8254835151ºE 27-MAR-62 00:00:00 1430.000000 MALGA CAMPON +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F22030 A 46.0508253483ºN 12.0619251800ºE 27-MAR-62 00:00:00 300.000000 ZANUSSI MEL +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F23027 A 46.0220149684ºN 11.9077995458ºE 27-MAR-62 00:00:00 270.000000 FELTRE OSPEDALE +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F24086 A 46.0632841167ºN 11.6096598449ºE 27-MAR-62 00:00:00 860.000000 BAILO CASTEL TESINO +w Waypoint,0,0.0,16777215,255,1,7,,0.0 +W F25045 A 46.0571933560ºN 11.8888581427ºE 27-MAR-62 00:00:00 450.000000 CASA SCEICCO +w Waypoint,0,0.0,16777215,255,1,7,,0.0 + + diff --git a/reference/compegps.wpt.gz b/reference/compegps.wpt.gz new file mode 100644 index 0000000000000000000000000000000000000000..3f4566b93b4cc9102ff7032356f8c95961e55f3f GIT binary patch literal 967 zcmV;&133I2iwFo#4PZk617mM(aAjw3b1rvqbO4=}zmDTL495FBg}Q690V$FCbDiQS zSpkk6SWX7m?#gR!w>aRiueMLObYjN?+!!;S%pipkn?LLO_>m{2UQR`M+FX^w&5Ke; zKqOF6k==m~8s&m`) zNyS@g;^sf~^4HHF-~ayS-z{wAms_;XIgPy4%v;>L?H1+o14DzEFu+@FEutMUEC`bg z9^b|=Gex}Rwp=f%JLW2>W2*Zut-~;&&2$=wEDt3dF+7t8aKXNfq0NlZ_o?gR>6BY_ zi*;)H+^pmvFnZ)LhP`EHdE(HXHth5XS}GpQ8ArR_9#Sm3KgPEKh{aTFYT9@0c7jBQ2D-&+?@$m)y1D(duhX zW#tKYARhJbs6Da{`k_bgY(oHqg)Sj}B2=m5_I&q6C-#i{eV411AVIox1Q}l3QIL0k zoP{w4VYskh&@h93SjgL|mYrZ9&clhw}1cd1s`y zSVg~Ui>B==sb9tOC96YJ0@JK)5j3MBLx+mc)=GFkY=J|LStoe!D>Ao8ynRTBXMIAL zbRg}BB^D+fSeu~bYvCZ|#@Uyxq(iFPMs@k9_Nl(5L;9E|PZECZ2$^5b!bF0`p$jD8 z@%Bl~Ajh`(7E7zjrS1CTwO&PFK|f6aRvVVTDJux1KT$6b$T98AgJ6Fx)z_rzdxqzA zVmPqV5F;B5crx?=a3pegU|1Mp7I->>I?60xRaTyhV=4ssnW*k@Dr=2QFii`ozz}vc z^#GC>>m9P)}Jm>A?C&-FzXDrrFC zXAT+C+L|TJU#%}CHhom}waQ}{roLaLytFz^%9}8}xH#~+%#k;Yyf7W)#wW)))-tMx zJX+@f{c4G0kcx&LX)MFZqJ)50WN9wUr|>N{*HZEj1gnah*#-h4B3M7VK7ex}u%yzG z4d%wbORppdWl^fvd4Obb9RWmcPqM+f2Y_s_c37Nf!2^C?Q}!|6^LKEgOoEb|b`=EA p6Nw!LSsv}=0Qtx~lz4uBQHe!%gDT~!`f&Bl<~Mq?Bfwq^008|r-Om63 literal 0 HcmV?d00001 diff --git a/reference/cototestmarker.gpx b/reference/cototestmarker.gpx index de942e558..1f04db89d 100644 --- a/reference/cototestmarker.gpx +++ b/reference/cototestmarker.gpx @@ -1,21 +1,21 @@ - + - + GC2663 - GC2663 + New Orleans Bon Chance (Good Luck) Cache-Cam by CrotalusRex and Mimichan New Orleans Bon Chance (Good Luck) Cache-Cam by CrotalusRex and Mimichan Geocache GCMK1V - GCMK1V + Randeck Maar Earthcache by Border Randeck Maar Earthcache by Border Earthcache diff --git a/reference/cototesttrack.csv b/reference/cototesttrack.csv index d5aee706c..d62e71c48 100644 --- a/reference/cototesttrack.csv +++ b/reference/cototesttrack.csv @@ -1,135 +1,135 @@ -48.557327,8.961583,,RPT001,RPT001,,395, 1.9,1122371309, 0.8, 1.2, 1.5,10,3d -48.557327,8.961585,,RPT002,RPT002,,395, 0.5,1122371311, 0.8, 1.2, 1.5,9,3d -48.557353,8.961542,,RPT003,RPT003,,395, 1.2,1122371313, 0.9, 1.3, 1.6,10,3d -48.557388,8.961457,,RPT004,RPT004,,395, 3.5,1122371315, 0.9, 1.3, 1.6,9,3d -48.557395,8.961412,,RPT005,RPT005,,395, 3.7,1122371316, 0.9, 1.3, 1.6,10,3d -48.557390,8.961370,,RPT006,RPT006,,395, 3.0,1122371317, 0.8, 1.2, 1.5,10,3d -48.557360,8.961295,,RPT007,RPT007,,395, 3.3,1122371319, 0.9, 1.4, 1.7,9,3d -48.557350,8.961223,,RPT008,RPT008,,395, 2.6,1122371321, 0.8, 1.2, 1.5,10,3d -48.557385,8.961148,,RPT009,RPT009,,396, 2.4,1122371324, 1.0, 1.6, 1.9,9,3d -48.557427,8.961158,,RPT010,RPT010,,395, 1.8,1122371326, 0.8, 1.2, 1.5,10,3d -48.557473,8.961232,,RPT011,RPT011,,396, 3.2,1122371328, 0.8, 1.2, 1.5,10,3d -48.557523,8.961327,,RPT012,RPT012,,396, 4.3,1122371330, 1.0, 1.6, 1.9,9,3d -48.557547,8.961410,,RPT013,RPT013,,396, 3.0,1122371332, 0.8, 1.2, 1.5,10,3d -48.557493,8.961597,,RPT014,RPT014,,396, 5.2,1122371335, 1.2, 2.0, 2.3,9,3d -48.557405,8.961743,,RPT015,RPT015,,396, 6.8,1122371337, 0.8, 1.2, 1.5,10,3d -48.557295,8.961937,,RPT016,RPT016,,395, 8.9,1122371339, 0.8, 1.2, 1.5,10,3d -48.557295,8.961937,,RPT017,RPT017,,395, 8.9,1122371339, 0.8, 1.2, 1.5,10,3d -48.557113,8.962262,,RPT018,RPT018,,395, 10.4,1122371342, 0.8, 1.2, 1.5,10,3d -48.557050,8.962375,,RPT019,RPT019,,395, 10.8,1122371343, 0.8, 1.2, 1.5,10,3d -48.556857,8.962722,,RPT020,RPT020,,395, 11.1,1122371346, 1.2, 1.5, 1.9,7,3d -48.556725,8.962953,,RPT021,RPT021,,395, 11.3,1122371348, 1.4, 2.3, 2.7,6,3d -48.556658,8.963070,,RPT022,RPT022,,395, 11.3,1122371349, 1.4, 2.3, 2.7,6,3d -48.556522,8.963310,,RPT023,RPT023,,395, 11.3,1122371351, 1.2, 2.2, 2.5,7,3d -48.556377,8.963557,,RPT024,RPT024,,394, 11.9,1122371353, 1.2, 2.0, 2.3,8,3d -48.556212,8.963793,,RPT025,RPT025,,394, 12.4,1122371355, 1.4, 2.0, 2.5,5,3d -48.556020,8.963990,,RPT026,RPT026,,393, 13.1,1122371357, 1.3, 2.3, 2.7,6,3d -48.555918,8.964075,,RPT027,RPT027,,393, 12.8,1122371358, 1.3, 2.0, 2.4,5,3d -48.555717,8.964222,,RPT028,RPT028,,393, 12.4,1122371360, 3.9, 6.4, 7.5,4,3d -48.555523,8.964363,,RPT029,RPT029,,392, 12.2,1122371362, 30.7, 41.0, 51.3,4,2d -48.555345,8.964542,,RPT030,RPT030,,392, 11.6,1122371364, 1.0, 1.6, 1.9,9,3d -48.555177,8.964760,,RPT031,RPT031,,392, 12.5,1122371366, 1.2, 1.9, 2.3,6,3d -48.555020,8.964978,,RPT032,RPT032,,392, 12.2,1122371368, 1.4, 2.3, 2.7,7,3d -48.554947,8.965077,,RPT033,RPT033,,392, 11.0,1122371369, 1.2, 2.2, 2.5,7,3d -48.554795,8.965253,,RPT034,RPT034,,392, 10.7,1122371371, 1.4, 2.4, 2.7,6,3d -48.554627,8.965418,,RPT035,RPT035,,391, 11.3,1122371373, 1.3, 2.8, 3.1,6,3d -48.554448,8.965578,,RPT036,RPT036,,391, 11.4,1122371375, 3.2, 3.5, 4.7,4,3d -48.554302,8.965727,,RPT037,RPT037,,390, 10.7,1122371377, 1.7, 2.3, 2.9,5,3d -48.554215,8.965882,,RPT038,RPT038,,391, 8.3,1122371379, 1.2, 2.2, 2.5,7,3d -48.554243,8.966045,,RPT039,RPT039,,391, 6.5,1122371381, 1.3, 2.0, 2.4,7,3d -48.554282,8.966232,,RPT040,RPT040,,391, 6.9,1122371383, 1.5, 4.1, 4.3,5,3d -48.554318,8.966453,,RPT041,RPT041,,391, 8.4,1122371385, 1.4, 2.4, 2.7,6,3d -48.554350,8.966680,,RPT042,RPT042,,392, 8.5,1122371387, 1.4, 2.5, 2.9,6,3d -48.554378,8.966915,,RPT043,RPT043,,392, 8.8,1122371389, 1.5, 4.1, 4.3,5,3d -48.554408,8.967123,,RPT044,RPT044,,393, 8.6,1122371391, 2.1, 2.3, 3.1,5,3d -48.554463,8.967297,,RPT045,RPT045,,394, 7.3,1122371393, 1.2, 1.8, 2.2,7,3d -48.554517,8.967438,,RPT046,RPT046,,395, 6.4,1122371395, 1.2, 1.9, 2.3,7,3d -48.554565,8.967590,,RPT047,RPT047,,395, 6.0,1122371397, 1.2, 1.9, 2.2,7,3d -48.554615,8.967743,,RPT048,RPT048,,395, 6.4,1122371399, 1.4, 2.3, 2.7,6,3d -48.554700,8.967838,,RPT049,RPT049,,396, 6.1,1122371401, 1.3, 2.3, 2.7,7,3d -48.554800,8.967820,,RPT050,RPT050,,397, 5.5,1122371403, 1.2, 2.0, 2.3,8,3d -48.554897,8.967800,,RPT051,RPT051,,396, 5.5,1122371405, 2.6, 3.1, 4.1,6,3d -48.555007,8.967795,,RPT052,RPT052,,396, 5.6,1122371407, 2.4, 3.1, 3.9,6,3d -48.555125,8.967822,,RPT053,RPT053,,396, 6.5,1122371409, 2.3, 2.2, 3.1,6,3d -48.555218,8.967930,,RPT054,RPT054,,397, 6.6,1122371411, 0.9, 1.3, 1.6,8,3d -48.555298,8.968085,,RPT055,RPT055,,399, 7.2,1122371413, 2.1, 2.3, 3.1,5,3d -48.555385,8.968235,,RPT056,RPT056,,400, 7.2,1122371415, 1.2, 1.8, 2.2,7,3d -48.555455,8.968420,,RPT057,RPT057,,401, 7.5,1122371417, 1.4, 2.3, 2.7,6,3d -48.555515,8.968630,,RPT058,RPT058,,402, 8.4,1122371419, 1.4, 2.3, 2.7,6,3d -48.555562,8.968847,,RPT059,RPT059,,403, 8.5,1122371421, 1.2, 1.8, 2.2,7,3d -48.555613,8.969055,,RPT060,RPT060,,403, 8.4,1122371423, 1.2, 1.8, 2.2,7,3d -48.555665,8.969248,,RPT061,RPT061,,403, 7.9,1122371425, 1.4, 2.3, 2.7,6,3d -48.555727,8.969428,,RPT062,RPT062,,403, 7.4,1122371427, 1.4, 2.3, 2.7,6,3d -48.555790,8.969582,,RPT063,RPT063,,403, 6.8,1122371429, 1.4, 2.3, 2.7,6,3d -48.555870,8.969733,,RPT064,RPT064,,404, 6.7,1122371431, 1.1, 1.6, 2.0,8,3d -48.555958,8.969892,,RPT065,RPT065,,404, 7.5,1122371433, 0.9, 1.3, 1.6,9,3d -48.556038,8.970065,,RPT066,RPT066,,404, 7.7,1122371435, 1.3, 1.8, 2.2,7,3d -48.556113,8.970243,,RPT067,RPT067,,404, 7.8,1122371437, 1.3, 1.8, 2.2,7,3d -48.556180,8.970410,,RPT068,RPT068,,404, 7.5,1122371439, 1.4, 2.3, 2.7,6,3d -48.556238,8.970570,,RPT069,RPT069,,404, 6.8,1122371441, 0.9, 1.4, 1.7,8,3d -48.556307,8.970727,,RPT070,RPT070,,404, 6.9,1122371443, 1.3, 1.8, 2.2,7,3d -48.556397,8.970867,,RPT071,RPT071,,404, 7.2,1122371445, 1.3, 2.3, 2.7,7,3d -48.556498,8.970997,,RPT072,RPT072,,404, 7.4,1122371447, 1.5, 4.1, 4.4,5,3d -48.556607,8.971127,,RPT073,RPT073,,403, 7.6,1122371449, 1.5, 2.3, 2.7,6,3d -48.556720,8.971252,,RPT074,RPT074,,403, 7.8,1122371451, 1.3, 2.8, 3.1,6,3d -48.556835,8.971373,,RPT075,RPT075,,404, 7.8,1122371453, 1.1, 1.7, 2.0,8,3d -48.556948,8.971477,,RPT076,RPT076,,404, 7.6,1122371455, 1.1, 1.6, 2.0,8,3d -48.557075,8.971538,,RPT077,RPT077,,406, 7.2,1122371457, 1.6, 1.8, 2.4,8,3d -48.557210,8.971575,,RPT078,RPT078,,407, 7.3,1122371459, 1.2, 2.0, 2.3,8,3d -48.557345,8.971608,,RPT079,RPT079,,407, 7.7,1122371461, 1.0, 1.6, 1.9,9,3d -48.557470,8.971637,,RPT080,RPT080,,407, 7.2,1122371463, 1.1, 1.7, 2.0,8,3d -48.557538,8.971660,,RPT081,RPT081,,406, 5.4,1122371465, 1.1, 1.7, 2.0,8,3d -48.557570,8.971673,,RPT082,RPT082,,406, 2.2,1122371467, 0.9, 1.4, 1.7,9,3d -48.557622,8.971690,,RPT083,RPT083,,406, 2.5,1122371469, 1.3, 2.8, 3.1,6,3d -48.557678,8.971717,,RPT084,RPT084,,405, 3.4,1122371471, 1.5, 2.3, 2.7,6,3d -48.557730,8.971812,,RPT085,RPT085,,406, 3.9,1122371473, 1.2, 1.8, 2.2,7,3d -48.557775,8.971957,,RPT086,RPT086,,407, 5.9,1122371475, 0.9, 1.3, 1.6,9,3d -48.557828,8.972137,,RPT087,RPT087,,409, 6.8,1122371477, 1.1, 1.6, 2.0,8,3d -48.557883,8.972347,,RPT088,RPT088,,409, 8.3,1122371479, 1.0, 1.5, 1.7,8,3d -48.557937,8.972573,,RPT089,RPT089,,409, 8.7,1122371481, 1.0, 1.5, 1.8,7,3d -48.558018,8.972813,,RPT090,RPT090,,411, 9.4,1122371483, 1.3, 1.8, 2.3,7,3d -48.558095,8.973078,,RPT091,RPT091,,413, 10.5,1122371485, 1.3, 1.8, 2.3,7,3d -48.558175,8.973340,,RPT092,RPT092,,414, 10.7,1122371487, 1.3, 1.8, 2.3,7,3d -48.558255,8.973603,,RPT093,RPT093,,416, 10.6,1122371489, 1.0, 1.5, 1.7,8,3d -48.558335,8.973867,,RPT094,RPT094,,416, 10.7,1122371491, 1.3, 1.8, 2.3,7,3d -48.558420,8.974128,,RPT095,RPT095,,417, 10.6,1122371493, 1.9, 2.0, 2.7,6,3d -48.558505,8.974393,,RPT096,RPT096,,418, 10.7,1122371495, 1.5, 2.3, 2.7,6,3d -48.558592,8.974660,,RPT097,RPT097,,419, 10.9,1122371497, 1.3, 1.8, 2.3,7,3d -48.558677,8.974927,,RPT098,RPT098,,420, 10.9,1122371499, 1.3, 1.8, 2.3,7,3d -48.558772,8.975185,,RPT099,RPT099,,422, 10.8,1122371501, 0.9, 1.3, 1.6,9,3d -48.558868,8.975437,,RPT100,RPT100,,423, 10.7,1122371503, 1.3, 1.9, 2.3,6,3d -48.558970,8.975678,,RPT101,RPT101,,424, 10.6,1122371505, 1.0, 1.5, 1.8,7,3d -48.559053,8.975923,,RPT102,RPT102,,426, 10.4,1122371507, 1.2, 1.8, 2.2,6,3d -48.559093,8.976192,,RPT103,RPT103,,427, 9.6,1122371509, 1.0, 1.6, 1.9,9,3d -48.559093,8.976475,,RPT104,RPT104,,429, 10.4,1122371511, 1.0, 1.6, 1.9,9,3d -48.559070,8.976762,,RPT105,RPT105,,432, 10.6,1122371513, 0.8, 1.2, 1.5,10,3d -48.559052,8.977048,,RPT106,RPT106,,434, 10.7,1122371515, 0.9, 1.4, 1.7,9,3d -48.559067,8.977337,,RPT107,RPT107,,436, 10.6,1122371517, 0.9, 1.4, 1.7,9,3d -48.559103,8.977623,,RPT108,RPT108,,437, 10.7,1122371519, 1.2, 1.8, 2.2,7,3d -48.559152,8.977908,,RPT109,RPT109,,439, 10.7,1122371521, 1.2, 1.8, 2.2,7,3d -48.559203,8.978187,,RPT110,RPT110,,440, 10.7,1122371523, 2.3, 2.1, 3.1,6,3d -48.559275,8.978455,,RPT111,RPT111,,442, 10.8,1122371525, 1.0, 1.6, 1.9,9,3d -48.559373,8.978698,,RPT112,RPT112,,444, 10.6,1122371527, 1.0, 1.6, 1.9,9,3d -48.559490,8.978930,,RPT113,RPT113,,446, 10.6,1122371529, 0.9, 1.3, 1.6,8,3d -48.559628,8.979135,,RPT114,RPT114,,448, 10.7,1122371531, 1.0, 1.6, 1.9,9,3d -48.559780,8.979312,,RPT115,RPT115,,449, 10.6,1122371533, 1.2, 2.0, 2.3,8,3d -48.559935,8.979483,,RPT116,RPT116,,451, 10.5,1122371535, 1.0, 1.6, 1.9,9,3d -48.560095,8.979653,,RPT117,RPT117,,453, 10.7,1122371537, 1.0, 1.6, 1.9,9,3d -48.560253,8.979823,,RPT118,RPT118,,455, 10.7,1122371539, 1.0, 1.6, 1.9,9,3d -48.560413,8.979993,,RPT119,RPT119,,456, 10.8,1122371541, 1.7, 1.8, 2.4,8,3d -48.560567,8.980157,,RPT120,RPT120,,458, 10.5,1122371543, 1.7, 1.8, 2.4,8,3d -48.560713,8.980332,,RPT121,RPT121,,460, 10.3,1122371545, 1.7, 1.8, 2.4,8,3d -48.560833,8.980553,,RPT122,RPT122,,462, 10.3,1122371547, 1.2, 2.0, 2.3,8,3d -48.560907,8.980828,,RPT123,RPT123,,463, 10.8,1122371549, 2.4, 3.1, 3.9,7,3d -48.560930,8.981137,,RPT124,RPT124,,465, 11.3,1122371551, 1.2, 2.0, 2.3,8,3d -48.560932,8.981452,,RPT125,RPT125,,467, 11.5,1122371553, 1.3, 2.3, 2.7,7,3d -48.560948,8.981762,,RPT126,RPT126,,469, 11.5,1122371555, 1.3, 2.3, 2.7,7,3d -48.560988,8.982068,,RPT127,RPT127,,471, 11.5,1122371557, 1.5, 4.1, 4.4,5,3d -48.561040,8.982372,,RPT128,RPT128,,473, 11.5,1122371559, 1.2, 1.8, 2.2,6,3d -48.561098,8.982663,,RPT129,RPT129,,474, 11.3,1122371561, 1.3, 1.9, 2.3,6,3d -48.561193,8.982927,,RPT130,RPT130,,475, 11.0,1122371563, 1.1, 1.6, 2.0,8,3d -48.561270,8.983170,,RPT131,RPT131,,476, 10.4,1122371565, 0.9, 1.3, 1.6,9,3d -48.561337,8.983385,,RPT132,RPT132,,477, 8.9,1122371567, 0.8, 1.3, 1.5,9,3d -48.561395,8.983598,,RPT133,RPT133,,477, 8.6,1122371569, 0.9, 1.3, 1.6,9,3d -48.561447,8.983807,,RPT134,RPT134,,477, 8.4,1122371571, 1.1, 1.6, 2.0,8,3d -48.561483,8.983955,,RPT135,RPT135,,477, 6.6,1122371573, 1.1, 1.8, 2.1,8,3d +48.557327,8.961583,,,,,395, 1.9,1122371309, 0.8, 1.2, 1.5,10,3d +48.557327,8.961585,,,,,395, 0.5,1122371311, 0.8, 1.2, 1.5,9,3d +48.557353,8.961542,,,,,395, 1.2,1122371313, 0.9, 1.3, 1.6,10,3d +48.557388,8.961457,,,,,395, 3.5,1122371315, 0.9, 1.3, 1.6,9,3d +48.557395,8.961412,,,,,395, 3.7,1122371316, 0.9, 1.3, 1.6,10,3d +48.557390,8.961370,,,,,395, 3.0,1122371317, 0.8, 1.2, 1.5,10,3d +48.557360,8.961295,,,,,395, 3.3,1122371319, 0.9, 1.4, 1.7,9,3d +48.557350,8.961223,,,,,395, 2.6,1122371321, 0.8, 1.2, 1.5,10,3d +48.557385,8.961148,,,,,396, 2.4,1122371324, 1.0, 1.6, 1.9,9,3d +48.557427,8.961158,,,,,395, 1.8,1122371326, 0.8, 1.2, 1.5,10,3d +48.557473,8.961232,,,,,396, 3.2,1122371328, 0.8, 1.2, 1.5,10,3d +48.557523,8.961327,,,,,396, 4.3,1122371330, 1.0, 1.6, 1.9,9,3d +48.557547,8.961410,,,,,396, 3.0,1122371332, 0.8, 1.2, 1.5,10,3d +48.557493,8.961597,,,,,396, 5.2,1122371335, 1.2, 2.0, 2.3,9,3d +48.557405,8.961743,,,,,396, 6.8,1122371337, 0.8, 1.2, 1.5,10,3d +48.557295,8.961937,,,,,395, 8.9,1122371339, 0.8, 1.2, 1.5,10,3d +48.557295,8.961937,,,,,395, 8.9,1122371339, 0.8, 1.2, 1.5,10,3d +48.557113,8.962262,,,,,395, 10.4,1122371342, 0.8, 1.2, 1.5,10,3d +48.557050,8.962375,,,,,395, 10.8,1122371343, 0.8, 1.2, 1.5,10,3d +48.556857,8.962722,,,,,395, 11.1,1122371346, 1.2, 1.5, 1.9,7,3d +48.556725,8.962953,,,,,395, 11.3,1122371348, 1.4, 2.3, 2.7,6,3d +48.556658,8.963070,,,,,395, 11.3,1122371349, 1.4, 2.3, 2.7,6,3d +48.556522,8.963310,,,,,395, 11.3,1122371351, 1.2, 2.2, 2.5,7,3d +48.556377,8.963557,,,,,394, 11.9,1122371353, 1.2, 2.0, 2.3,8,3d +48.556212,8.963793,,,,,394, 12.4,1122371355, 1.4, 2.0, 2.5,5,3d +48.556020,8.963990,,,,,393, 13.1,1122371357, 1.3, 2.3, 2.7,6,3d +48.555918,8.964075,,,,,393, 12.8,1122371358, 1.3, 2.0, 2.4,5,3d +48.555717,8.964222,,,,,393, 12.4,1122371360, 3.9, 6.4, 7.5,4,3d +48.555523,8.964363,,,,,392, 12.2,1122371362, 30.7, 41.0, 51.3,4,2d +48.555345,8.964542,,,,,392, 11.6,1122371364, 1.0, 1.6, 1.9,9,3d +48.555177,8.964760,,,,,392, 12.5,1122371366, 1.2, 1.9, 2.3,6,3d +48.555020,8.964978,,,,,392, 12.2,1122371368, 1.4, 2.3, 2.7,7,3d +48.554947,8.965077,,,,,392, 11.0,1122371369, 1.2, 2.2, 2.5,7,3d +48.554795,8.965253,,,,,392, 10.7,1122371371, 1.4, 2.4, 2.7,6,3d +48.554627,8.965418,,,,,391, 11.3,1122371373, 1.3, 2.8, 3.1,6,3d +48.554448,8.965578,,,,,391, 11.4,1122371375, 3.2, 3.5, 4.7,4,3d +48.554302,8.965727,,,,,390, 10.7,1122371377, 1.7, 2.3, 2.9,5,3d +48.554215,8.965882,,,,,391, 8.3,1122371379, 1.2, 2.2, 2.5,7,3d +48.554243,8.966045,,,,,391, 6.5,1122371381, 1.3, 2.0, 2.4,7,3d +48.554282,8.966232,,,,,391, 6.9,1122371383, 1.5, 4.1, 4.3,5,3d +48.554318,8.966453,,,,,391, 8.4,1122371385, 1.4, 2.4, 2.7,6,3d +48.554350,8.966680,,,,,392, 8.5,1122371387, 1.4, 2.5, 2.9,6,3d +48.554378,8.966915,,,,,392, 8.8,1122371389, 1.5, 4.1, 4.3,5,3d +48.554408,8.967123,,,,,393, 8.6,1122371391, 2.1, 2.3, 3.1,5,3d +48.554463,8.967297,,,,,394, 7.3,1122371393, 1.2, 1.8, 2.2,7,3d +48.554517,8.967438,,,,,395, 6.4,1122371395, 1.2, 1.9, 2.3,7,3d +48.554565,8.967590,,,,,395, 6.0,1122371397, 1.2, 1.9, 2.2,7,3d +48.554615,8.967743,,,,,395, 6.4,1122371399, 1.4, 2.3, 2.7,6,3d +48.554700,8.967838,,,,,396, 6.1,1122371401, 1.3, 2.3, 2.7,7,3d +48.554800,8.967820,,,,,397, 5.5,1122371403, 1.2, 2.0, 2.3,8,3d +48.554897,8.967800,,,,,396, 5.5,1122371405, 2.6, 3.1, 4.1,6,3d +48.555007,8.967795,,,,,396, 5.6,1122371407, 2.4, 3.1, 3.9,6,3d +48.555125,8.967822,,,,,396, 6.5,1122371409, 2.3, 2.2, 3.1,6,3d +48.555218,8.967930,,,,,397, 6.6,1122371411, 0.9, 1.3, 1.6,8,3d +48.555298,8.968085,,,,,399, 7.2,1122371413, 2.1, 2.3, 3.1,5,3d +48.555385,8.968235,,,,,400, 7.2,1122371415, 1.2, 1.8, 2.2,7,3d +48.555455,8.968420,,,,,401, 7.5,1122371417, 1.4, 2.3, 2.7,6,3d +48.555515,8.968630,,,,,402, 8.4,1122371419, 1.4, 2.3, 2.7,6,3d +48.555562,8.968847,,,,,403, 8.5,1122371421, 1.2, 1.8, 2.2,7,3d +48.555613,8.969055,,,,,403, 8.4,1122371423, 1.2, 1.8, 2.2,7,3d +48.555665,8.969248,,,,,403, 7.9,1122371425, 1.4, 2.3, 2.7,6,3d +48.555727,8.969428,,,,,403, 7.4,1122371427, 1.4, 2.3, 2.7,6,3d +48.555790,8.969582,,,,,403, 6.8,1122371429, 1.4, 2.3, 2.7,6,3d +48.555870,8.969733,,,,,404, 6.7,1122371431, 1.1, 1.6, 2.0,8,3d +48.555958,8.969892,,,,,404, 7.5,1122371433, 0.9, 1.3, 1.6,9,3d +48.556038,8.970065,,,,,404, 7.7,1122371435, 1.3, 1.8, 2.2,7,3d +48.556113,8.970243,,,,,404, 7.8,1122371437, 1.3, 1.8, 2.2,7,3d +48.556180,8.970410,,,,,404, 7.5,1122371439, 1.4, 2.3, 2.7,6,3d +48.556238,8.970570,,,,,404, 6.8,1122371441, 0.9, 1.4, 1.7,8,3d +48.556307,8.970727,,,,,404, 6.9,1122371443, 1.3, 1.8, 2.2,7,3d +48.556397,8.970867,,,,,404, 7.2,1122371445, 1.3, 2.3, 2.7,7,3d +48.556498,8.970997,,,,,404, 7.4,1122371447, 1.5, 4.1, 4.4,5,3d +48.556607,8.971127,,,,,403, 7.6,1122371449, 1.5, 2.3, 2.7,6,3d +48.556720,8.971252,,,,,403, 7.8,1122371451, 1.3, 2.8, 3.1,6,3d +48.556835,8.971373,,,,,404, 7.8,1122371453, 1.1, 1.7, 2.0,8,3d +48.556948,8.971477,,,,,404, 7.6,1122371455, 1.1, 1.6, 2.0,8,3d +48.557075,8.971538,,,,,406, 7.2,1122371457, 1.6, 1.8, 2.4,8,3d +48.557210,8.971575,,,,,407, 7.3,1122371459, 1.2, 2.0, 2.3,8,3d +48.557345,8.971608,,,,,407, 7.7,1122371461, 1.0, 1.6, 1.9,9,3d +48.557470,8.971637,,,,,407, 7.2,1122371463, 1.1, 1.7, 2.0,8,3d +48.557538,8.971660,,,,,406, 5.4,1122371465, 1.1, 1.7, 2.0,8,3d +48.557570,8.971673,,,,,406, 2.2,1122371467, 0.9, 1.4, 1.7,9,3d +48.557622,8.971690,,,,,406, 2.5,1122371469, 1.3, 2.8, 3.1,6,3d +48.557678,8.971717,,,,,405, 3.4,1122371471, 1.5, 2.3, 2.7,6,3d +48.557730,8.971812,,,,,406, 3.9,1122371473, 1.2, 1.8, 2.2,7,3d +48.557775,8.971957,,,,,407, 5.9,1122371475, 0.9, 1.3, 1.6,9,3d +48.557828,8.972137,,,,,409, 6.8,1122371477, 1.1, 1.6, 2.0,8,3d +48.557883,8.972347,,,,,409, 8.3,1122371479, 1.0, 1.5, 1.7,8,3d +48.557937,8.972573,,,,,409, 8.7,1122371481, 1.0, 1.5, 1.8,7,3d +48.558018,8.972813,,,,,411, 9.4,1122371483, 1.3, 1.8, 2.3,7,3d +48.558095,8.973078,,,,,413, 10.5,1122371485, 1.3, 1.8, 2.3,7,3d +48.558175,8.973340,,,,,414, 10.7,1122371487, 1.3, 1.8, 2.3,7,3d +48.558255,8.973603,,,,,416, 10.6,1122371489, 1.0, 1.5, 1.7,8,3d +48.558335,8.973867,,,,,416, 10.7,1122371491, 1.3, 1.8, 2.3,7,3d +48.558420,8.974128,,,,,417, 10.6,1122371493, 1.9, 2.0, 2.7,6,3d +48.558505,8.974393,,,,,418, 10.7,1122371495, 1.5, 2.3, 2.7,6,3d +48.558592,8.974660,,,,,419, 10.9,1122371497, 1.3, 1.8, 2.3,7,3d +48.558677,8.974927,,,,,420, 10.9,1122371499, 1.3, 1.8, 2.3,7,3d +48.558772,8.975185,,,,,422, 10.8,1122371501, 0.9, 1.3, 1.6,9,3d +48.558868,8.975437,,,,,423, 10.7,1122371503, 1.3, 1.9, 2.3,6,3d +48.558970,8.975678,,,,,424, 10.6,1122371505, 1.0, 1.5, 1.8,7,3d +48.559053,8.975923,,,,,426, 10.4,1122371507, 1.2, 1.8, 2.2,6,3d +48.559093,8.976192,,,,,427, 9.6,1122371509, 1.0, 1.6, 1.9,9,3d +48.559093,8.976475,,,,,429, 10.4,1122371511, 1.0, 1.6, 1.9,9,3d +48.559070,8.976762,,,,,432, 10.6,1122371513, 0.8, 1.2, 1.5,10,3d +48.559052,8.977048,,,,,434, 10.7,1122371515, 0.9, 1.4, 1.7,9,3d +48.559067,8.977337,,,,,436, 10.6,1122371517, 0.9, 1.4, 1.7,9,3d +48.559103,8.977623,,,,,437, 10.7,1122371519, 1.2, 1.8, 2.2,7,3d +48.559152,8.977908,,,,,439, 10.7,1122371521, 1.2, 1.8, 2.2,7,3d +48.559203,8.978187,,,,,440, 10.7,1122371523, 2.3, 2.1, 3.1,6,3d +48.559275,8.978455,,,,,442, 10.8,1122371525, 1.0, 1.6, 1.9,9,3d +48.559373,8.978698,,,,,444, 10.6,1122371527, 1.0, 1.6, 1.9,9,3d +48.559490,8.978930,,,,,446, 10.6,1122371529, 0.9, 1.3, 1.6,8,3d +48.559628,8.979135,,,,,448, 10.7,1122371531, 1.0, 1.6, 1.9,9,3d +48.559780,8.979312,,,,,449, 10.6,1122371533, 1.2, 2.0, 2.3,8,3d +48.559935,8.979483,,,,,451, 10.5,1122371535, 1.0, 1.6, 1.9,9,3d +48.560095,8.979653,,,,,453, 10.7,1122371537, 1.0, 1.6, 1.9,9,3d +48.560253,8.979823,,,,,455, 10.7,1122371539, 1.0, 1.6, 1.9,9,3d +48.560413,8.979993,,,,,456, 10.8,1122371541, 1.7, 1.8, 2.4,8,3d +48.560567,8.980157,,,,,458, 10.5,1122371543, 1.7, 1.8, 2.4,8,3d +48.560713,8.980332,,,,,460, 10.3,1122371545, 1.7, 1.8, 2.4,8,3d +48.560833,8.980553,,,,,462, 10.3,1122371547, 1.2, 2.0, 2.3,8,3d +48.560907,8.980828,,,,,463, 10.8,1122371549, 2.4, 3.1, 3.9,7,3d +48.560930,8.981137,,,,,465, 11.3,1122371551, 1.2, 2.0, 2.3,8,3d +48.560932,8.981452,,,,,467, 11.5,1122371553, 1.3, 2.3, 2.7,7,3d +48.560948,8.981762,,,,,469, 11.5,1122371555, 1.3, 2.3, 2.7,7,3d +48.560988,8.982068,,,,,471, 11.5,1122371557, 1.5, 4.1, 4.4,5,3d +48.561040,8.982372,,,,,473, 11.5,1122371559, 1.2, 1.8, 2.2,6,3d +48.561098,8.982663,,,,,474, 11.3,1122371561, 1.3, 1.9, 2.3,6,3d +48.561193,8.982927,,,,,475, 11.0,1122371563, 1.1, 1.6, 2.0,8,3d +48.561270,8.983170,,,,,476, 10.4,1122371565, 0.9, 1.3, 1.6,9,3d +48.561337,8.983385,,,,,477, 8.9,1122371567, 0.8, 1.3, 1.5,9,3d +48.561395,8.983598,,,,,477, 8.6,1122371569, 0.9, 1.3, 1.6,9,3d +48.561447,8.983807,,,,,477, 8.4,1122371571, 1.1, 1.6, 2.0,8,3d +48.561483,8.983955,,,,,477, 6.6,1122371573, 1.1, 1.8, 2.1,8,3d diff --git a/reference/dusky.gnuplot b/reference/dusky.gnuplot index 87fe2c4ba..952cfebe1 100644 --- a/reference/dusky.gnuplot +++ b/reference/dusky.gnuplot @@ -1,65 +1,65 @@ plot "-" with lines -0.0000 623.352000 -2.9718 711.933600 -3.2850 715.214400 -3.6167 715.214400 -5.5243 705.372000 -9.4129 659.440800 -23.4703 606.948000 -25.0162 610.228800 -30.9820 623.352000 -32.4677 616.790400 -34.3415 629.913600 -39.1519 639.756000 -40.1487 643.036800 -43.8551 639.756000 -45.1980 639.756000 -50.2415 643.036800 -50.7511 613.509600 -52.4188 652.879200 -59.6859 662.721600 -61.2516 698.810400 -71.6546 738.180000 -72.5283 764.426400 -87.9457 721.776000 -88.7923 725.056800 -91.6167 764.426400 -99.6578 902.220000 -99.8003 905.500800 -99.9720 905.500800 -100.1892 902.220000 -100.5724 882.535200 -102.0104 882.535200 -102.8041 875.973600 -103.0804 872.692800 -107.3975 921.904800 -107.9219 915.343200 -111.8075 977.678400 -112.3607 974.397600 -113.7989 1003.924800 -115.6245 967.836000 -119.3377 1082.664000 -120.3016 1040.013600 -122.6318 1030.171200 -125.0204 1056.417600 -125.1988 1089.225600 -127.7871 1076.102400 -129.8891 997.363200 -130.3262 974.397600 -130.9400 971.116800 -131.4143 1020.328800 -142.6996 935.028000 -147.6842 905.500800 -154.3627 902.220000 -155.0489 889.096800 -155.6592 872.692800 -156.1879 846.446400 -156.8340 869.412000 -157.3818 875.973600 -159.8910 846.446400 -159.9999 856.288800 -163.1963 866.131200 -164.7320 869.412000 -164.9323 859.569600 -165.1204 849.727200 +0.0000 623.359581 +2.9718 711.942258 +3.2850 715.223098 +3.6167 715.223098 +5.5243 705.380579 +9.4129 659.448820 +23.4703 606.955382 +25.0162 610.236221 +30.9820 623.359581 +32.4677 616.797901 +34.3415 629.921261 +39.1519 639.763781 +40.1487 643.044620 +43.8551 639.763781 +45.1980 639.763781 +50.2415 643.044620 +50.7511 613.517061 +52.4188 652.887140 +59.6859 662.729660 +61.2516 698.818899 +71.6546 738.188978 +72.5283 764.435697 +87.9457 721.784778 +88.7923 725.065618 +91.6167 764.435697 +99.6578 902.230973 +99.8003 905.511812 +99.9720 905.511812 +100.1892 902.230973 +100.5724 882.545933 +102.0104 882.545933 +102.8041 875.984253 +103.0804 872.703413 +107.3975 921.916012 +107.9219 915.354332 +111.8075 977.690290 +112.3607 974.409450 +113.7989 1003.937009 +115.6245 967.847771 +119.3377 1082.677167 +120.3016 1040.026248 +122.6318 1030.183729 +125.0204 1056.430448 +125.1988 1089.238847 +127.7871 1076.115487 +129.8891 997.375330 +130.3262 974.409450 +130.9400 971.128610 +131.4143 1020.341209 +142.6996 935.039372 +147.6842 905.511812 +154.3627 902.230973 +155.0489 889.107613 +155.6592 872.703413 +156.1879 846.456694 +156.8340 869.422573 +157.3818 875.984253 +159.8910 846.456694 +159.9999 856.299214 +163.1963 866.141734 +164.7320 869.422573 +164.9323 859.580054 +165.1204 849.737534 e diff --git a/reference/earth-expertgps.kml b/reference/earth-expertgps.kml new file mode 100644 index 000000000..3d97dacac --- /dev/null +++ b/reference/earth-expertgps.kml @@ -0,0 +1,3373 @@ + + + + GPS device + + + + + + + normal + #route_n + + + highlight + #route_h + + + + + + + + + normal + #track_n + + + highlight + #track_h + + + + + + + + + normal + #waypoint_n + + + highlight + #waypoint_h + + + + + Waypoints + + 5066 + 2001-11-28T21:05:28Z + #waypoint + + -71.119277,42.438878,44.586548 + + + + 5067 + 2001-06-02T03:26:55Z + #waypoint + + -71.119689,42.439227,57.607200 + + + + 5096 + 2001-11-16T23:03:38Z + #waypoint + + -71.116146,42.438917,44.826904 + + + + 5142 + 2001-11-28T21:05:28Z + #waypoint + + -71.122044,42.443904,50.594727 + + + + 5156 + 2001-06-02T03:26:58Z + #waypoint + + -71.121447,42.447298,127.711200 + + + + 5224 + 2001-06-02T03:26:59Z + #waypoint + + -71.125094,42.454873,96.926400 + + + + 5229 + 2001-06-02T03:26:59Z + #waypoint + + -71.124988,42.459079,82.600800 + + + + 5237 + 2001-06-02T03:26:59Z + #waypoint + + -71.124474,42.456979,82.905600 + + + + 5254 + 2001-11-28T21:05:28Z + #waypoint + + -71.120990,42.454401,66.696655 + + + + 5258 + 2001-11-07T23:53:41Z + #waypoint + + -71.121746,42.451442,74.627442 + + + + 5264 + 2001-11-28T21:05:28Z + #waypoint + + -71.120660,42.454404,65.254761 + + + + 526708 + 2001-06-02T03:27:00Z + #waypoint + + -71.121045,42.457761,77.419200 + + + + 526750 + 2001-06-02T03:27:00Z + #waypoint + + -71.120313,42.457089,74.676000 + + + + 527614 + 2001-11-07T23:53:41Z + #waypoint + + -71.119676,42.456592,78.713135 + + + + 527631 + 2001-11-07T23:53:41Z + #waypoint + + -71.119356,42.456252,78.713135 + + + + 5278 + 2001-06-02T03:27:00Z + #waypoint + + -71.119135,42.458148,68.275200 + + + + 5289 + 2001-06-02T03:27:01Z + #waypoint + + -71.117693,42.459377,64.008000 + + + + 5374FIRE + 2001-11-28T21:05:28Z + #waypoint + + -71.119828,42.464183,52.997925 + + + + 5376 + 2001-06-02T03:27:02Z + #waypoint + + -71.119399,42.465650,56.388000 + + + + 6006 + 2001-06-02T03:26:55Z + #waypoint + + -71.114456,42.439018,56.388000 + + + + 6006BLUE + 2001-11-28T21:05:28Z + #waypoint + + -71.114803,42.438594,46.028564 + + + + 6014MEADOW + 2001-11-28T21:05:28Z + #waypoint + + -71.113223,42.436757,37.616943 + + + + 6029 + 2001-06-02T03:26:55Z + #waypoint + + -71.113220,42.441754,56.388000 + + + + 6053 + 2001-06-02T03:27:05Z + #waypoint + + -71.109075,42.436243,50.292000 + + + + 6066 + 2001-06-02T03:26:57Z + #waypoint + + -71.107500,42.439250,25.603200 + + + + 6067 + 2001-06-02T03:26:57Z + #waypoint + + -71.107582,42.439764,34.442400 + + + + 6071 + 2001-06-02T03:26:57Z + #waypoint + + -71.105874,42.434766,30.480000 + + + + 6073 + 2001-06-02T03:26:56Z + #waypoint + + -71.106599,42.433304,15.240000 + + + + 6084 + 2001-06-02T03:26:57Z + #waypoint + + -71.104772,42.437338,37.795200 + + + + 6130 + 2001-06-02T03:26:55Z + #waypoint + + -71.110975,42.442196,64.008000 + + + + 6131 + 2001-06-02T03:26:58Z + #waypoint + + -71.111441,42.442981,64.008000 + + + + 6153 + 2001-06-02T03:27:05Z + #waypoint + + -71.108882,42.444773,62.788800 + + + + 6171 + 2001-06-02T03:27:05Z + #waypoint + + -71.106301,42.443592,55.473600 + + + + 6176 + 2001-06-02T03:27:04Z + #waypoint + + -71.106624,42.447804,62.484000 + + + + 6177 + 2001-06-02T03:27:04Z + #waypoint + + -71.106158,42.448448,62.179200 + + + + 6272 + 2001-06-02T03:26:55Z + #waypoint + + -71.106783,42.453415,69.799200 + + + + 6272 + 2001-06-02T03:26:56Z + #waypoint + + -71.107253,42.453434,73.152000 + + + + 6278 + 2001-06-02T03:27:04Z + #waypoint + + -71.106771,42.458298,70.104000 + + + + 6280 + 2001-11-16T23:03:38Z + #waypoint + + -71.105413,42.451430,57.564209 + + + + 6283 + 2001-11-16T23:03:38Z + #waypoint + + -71.105206,42.453845,66.696655 + + + + 6289 + 2001-11-16T23:03:38Z + #waypoint + + -71.106170,42.459986,72.945191 + + + + 6297 + 2001-06-02T03:27:04Z + #waypoint + + -71.105116,42.457616,72.847200 + + + + 6328 + 2001-06-02T03:27:02Z + #waypoint + + -71.113574,42.467110,53.644800 + + + + 6354 + 2001-06-02T03:27:03Z + #waypoint + + -71.109863,42.464202,43.891200 + + + + 635722 + 2001-06-02T03:27:02Z + #waypoint + + -71.110067,42.466459,48.768000 + + + + 635783 + 2001-06-02T03:27:02Z + #waypoint + + -71.109410,42.466557,49.072800 + + + + 6373 + 2001-06-02T03:27:03Z + #waypoint + + -71.107117,42.463495,62.484000 + + + + 6634 + 2001-06-02T03:26:56Z + #waypoint + + -71.110241,42.401051,3.962400 + + + + 6979 + 2001-06-02T03:26:56Z + #waypoint + + -71.106532,42.432621,13.411200 + + + + 6997 + 2001-11-16T23:03:38Z + #waypoint + + -71.107883,42.431033,34.012085 + + + + BEAR HILL + 2001-06-02T03:27:03Z + #waypoint + + -71.107360,42.465687,87.782400 + + + + BELLEVUE + 2001-06-02T00:18:15Z + #waypoint + + -71.107628,42.430950,23.469600 + + + + 6016 + 2001-11-28T21:05:28Z + #waypoint + + -71.114079,42.438666,43.384766 + + + + 5236BRIDGE + 2001-06-02T03:26:59Z + #waypoint + + -71.124651,42.456469,89.916000 + + + + 5376BRIDGE + 2001-06-02T03:27:01Z + #waypoint + + -71.119815,42.465759,55.473600 + + + + 6181CROSS + 2001-06-02T03:27:05Z + #waypoint + + -71.105878,42.442993,52.730400 + + + + 6042CROSS + 2001-06-02T03:27:05Z + #waypoint + + -71.109664,42.435472,45.110400 + + + + DARKHOLLPO + #waypoint + + -71.103646,42.458516,0.000000 + + + + 6121DEAD + 2001-06-02T03:26:57Z + #waypoint + + -71.112675,42.443109,56.083200 + + + + 5179DEAD + 2001-06-02T03:26:59Z + #waypoint + + -71.119298,42.449866,117.043200 + + + + 5299DEAD + 2001-06-02T03:27:01Z + #waypoint + + -71.116524,42.459629,69.494400 + + + + 5376DEAD + 2001-06-02T03:27:02Z + #waypoint + + -71.119148,42.465485,56.997600 + + + + 6353DEAD + 2001-06-02T03:27:03Z + #waypoint + + -71.109986,42.462776,46.939200 + + + + 6155DEAD + 2001-06-02T03:27:04Z + #waypoint + + -71.108784,42.446793,61.264800 + + + + GATE14 + 2001-06-02T03:26:59Z + #waypoint + + -71.126602,42.451204,110.947200 + + + + GATE16 + 2001-06-02T03:27:00Z + #waypoint + + -71.122078,42.458499,77.724000 + + + + GATE17 + 2001-06-02T03:27:01Z + #waypoint + + -71.119238,42.459376,65.836800 + + + + GATE19 + 2001-06-02T03:27:02Z + #waypoint + + -71.119240,42.466353,57.302400 + + + + GATE21 + 2001-06-02T03:27:03Z + #waypoint + + -71.107697,42.468655,49.377600 + + + + GATE24 + 2001-06-02T03:27:03Z + #waypoint + + -71.102973,42.456718,81.076800 + + + + GATE5 + 2001-11-28T21:05:28Z + #waypoint + + -71.107690,42.430847,21.515015 + + + + GATE6 + 2001-11-07T23:53:41Z + #waypoint + + -71.109236,42.431240,26.561890 + + + + 6077LOGS + 2001-06-02T00:18:16Z + #waypoint + + -71.106556,42.439502,32.004000 + + + + 5148NANEPA + 2001-11-07T23:53:41Z + #waypoint + + -71.122320,42.449765,119.809082 + + + + 5267OBSTAC + 2001-06-02T03:27:00Z + #waypoint + + -71.119845,42.457388,73.761600 + + + + PANTHRCAVE + 2001-11-07T23:53:41Z + #waypoint + + -71.109942,42.434980,45.307495 + + + + 5252PURPLE + 2001-11-07T23:53:41Z + #waypoint + + -71.121211,42.453256,77.992066 + + + + 5287WATER + 2001-06-02T03:27:01Z + #waypoint + + -71.117481,42.457734,67.970400 + + + + 5239ROAD + 2001-06-02T03:27:00Z + #waypoint + + -71.124574,42.459278,81.076800 + + + + 5278ROAD + 2001-06-02T03:27:01Z + #waypoint + + -71.118991,42.458782,67.360800 + + + + 5058ROAD + 2001-06-02T00:18:14Z + #waypoint + + -71.120925,42.439993,53.949600 + + + + SHEEPFOLD + 2001-06-02T00:18:13Z + #waypoint + + -71.106782,42.453415,69.799200 + + + + SOAPBOX + 2001-06-02T03:27:04Z + #waypoint + + -71.107483,42.455956,64.008000 + + + + 5376STREAM + 2001-11-07T23:53:41Z + #waypoint + + -71.119328,42.465913,64.533692 + + + + 5144SUMMIT + 2001-11-28T21:05:28Z + #waypoint + + -71.122845,42.445359,61.649902 + + + + 5150TANK + 2001-06-02T00:18:16Z + #waypoint + + -71.121676,42.441727,67.360800 + + + + + Tracks + + + + + Distance 4.8 mi + Min Alt 3.3 ft + Max Alt 23.0 ft + Max Speed 25.5 mph + ]]> + + + 2002-05-25T17:06:21Z + 2002-05-25T19:05:57Z + + + Points + + -0 + + + Longitude: -91.610350 + Latitude: 30.062183 + Altitude: 3.3 ft + Speed: 0.0 mph + Heading: 300.1 + + ]]> + + -91.610350 + 30.062183 + 66 + + 2002-05-25T17:06:21Z + #track + + -91.610350,30.062183,1.000000 + + + + -1 + + + Longitude: -91.610567 + Latitude: 30.062783 + Speed: 0.7 mph + Heading: 342.6 + + ]]> + + -91.610567 + 30.062783 + 66 + + 2002-05-25T17:09:55Z + #track + + -91.610567,30.062783,0.000000 + + + + -2 + + + Longitude: -91.608267 + Latitude: 30.062700 + Speed: 4.0 mph + Heading: 92.4 + + ]]> + + -91.608267 + 30.062700 + 66 + + 2002-05-25T17:12:00Z + #track + + -91.608267,30.062700,0.000000 + + + + -3 + + + Longitude: -91.607383 + Latitude: 30.062333 + Speed: 4.4 mph + Heading: 115.6 + + ]]> + + -91.607383 + 30.062333 + 66 + + 2002-05-25T17:12:48Z + #track + + -91.607383,30.062333,0.000000 + + + + -4 + + + Longitude: -91.605283 + Latitude: 30.061533 + Speed: 4.4 mph + Heading: 113.8 + + ]]> + + -91.605283 + 30.061533 + 66 + + 2002-05-25T17:14:41Z + #track + + -91.605283,30.061533,0.000000 + + + + -5 + + + Longitude: -91.599400 + Latitude: 30.059783 + Speed: 8.6 mph + Heading: 109.0 + + ]]> + + -91.599400 + 30.059783 + 66 + + 2002-05-25T17:17:16Z + #track + + -91.599400,30.059783,0.000000 + + + + -6 + + + Longitude: -91.596683 + Latitude: 30.057800 + Speed: 25.5 mph + Heading: 130.1 + + ]]> + + -91.596683 + 30.057800 + 66 + + 2002-05-25T17:17:46Z + #track + + -91.596683,30.057800,0.000000 + + + + -7 + + + Longitude: -91.594900 + Latitude: 30.055383 + Speed: 21.0 mph + Heading: 147.4 + + ]]> + + -91.594900 + 30.055383 + 66 + + 2002-05-25T17:18:20Z + #track + + -91.594900,30.055383,0.000000 + + + + -8 + + + Longitude: -91.592617 + Latitude: 30.053883 + Speed: 15.1 mph + Heading: 127.2 + + ]]> + + -91.592617 + 30.053883 + 66 + + 2002-05-25T17:19:01Z + #track + + -91.592617,30.053883,0.000000 + + + + -9 + + + Longitude: -91.589750 + Latitude: 30.049733 + Speed: 11.5 mph + Heading: 149.1 + + ]]> + + -91.589750 + 30.049733 + 66 + + 2002-05-25T17:20:46Z + #track + + -91.589750,30.049733,0.000000 + + + + -10 + + + Longitude: -91.589883 + Latitude: 30.049017 + Speed: 7.5 mph + Heading: 189.1 + + ]]> + + -91.589883 + 30.049017 + 66 + + 2002-05-25T17:21:10Z + #track + + -91.589883,30.049017,0.000000 + + + + -11 + + + Longitude: -91.592933 + Latitude: 30.048800 + Speed: 16.1 mph + Heading: 265.3 + + ]]> + + -91.592933 + 30.048800 + 66 + + 2002-05-25T17:21:51Z + #track + + -91.592933,30.048800,0.000000 + + + + -12 + + + Longitude: -91.596450 + Latitude: 30.046233 + Speed: 22.5 mph + Heading: 229.9 + + ]]> + + -91.596450 + 30.046233 + 66 + + 2002-05-25T17:22:35Z + #track + + -91.596450,30.046233,0.000000 + + + + -13 + + + Longitude: -91.598717 + Latitude: 30.045517 + Speed: 15.8 mph + Heading: 250.0 + + ]]> + + -91.598717 + 30.045517 + 66 + + 2002-05-25T17:23:08Z + #track + + -91.598717,30.045517,0.000000 + + + + -14 + + + Longitude: -91.600267 + Latitude: 30.047300 + Speed: 0.2 mph + Heading: 323.0 + + ]]> + + -91.600267 + 30.047300 + 66 + + 2002-05-25T18:04:23Z + #track + + -91.600267,30.047300,0.000000 + + + + -15 + + + Longitude: -91.599633 + Latitude: 30.047000 + Altitude: 6.6 ft + Speed: 1.5 mph + Heading: 118.7 + + ]]> + + -91.599633 + 30.047000 + 66 + + 2002-05-25T18:06:04Z + #track + + -91.599633,30.047000,2.000000 + + + + -16 + + + Longitude: -91.599467 + Latitude: 30.046433 + Speed: 2.3 mph + Heading: 165.8 + + ]]> + + -91.599467 + 30.046433 + 66 + + 2002-05-25T18:07:06Z + #track + + -91.599467,30.046433,0.000000 + + + + -17 + + + Longitude: -91.598950 + Latitude: 30.046200 + Altitude: 3.3 ft + Speed: 1.7 mph + Heading: 117.5 + + ]]> + + -91.598950 + 30.046200 + 66 + + 2002-05-25T18:08:18Z + #track + + -91.598950,30.046200,1.000000 + + + + -18 + + + Longitude: -91.597733 + Latitude: 30.046367 + Speed: 2.2 mph + Heading: 81.0 + + ]]> + + -91.597733 + 30.046367 + 66 + + 2002-05-25T18:10:20Z + #track + + -91.597733,30.046367,0.000000 + + + + -19 + + + Longitude: -91.597167 + Latitude: 30.046350 + Speed: 2.5 mph + Heading: 92.0 + + ]]> + + -91.597167 + 30.046350 + 66 + + 2002-05-25T18:11:09Z + #track + + -91.597167,30.046350,0.000000 + + + + -20 + + + Longitude: -91.596333 + Latitude: 30.046783 + Speed: 3.0 mph + Heading: 59.0 + + ]]> + + -91.596333 + 30.046783 + 66 + + 2002-05-25T18:12:18Z + #track + + -91.596333,30.046783,0.000000 + + + + -21 + + + Longitude: -91.595200 + Latitude: 30.047450 + Speed: 2.4 mph + Heading: 55.8 + + ]]> + + -91.595200 + 30.047450 + 66 + + 2002-05-25T18:14:22Z + #track + + -91.595200,30.047450,0.000000 + + + + -22 + + + Longitude: -91.594767 + Latitude: 30.047800 + Altitude: 6.6 ft + Speed: 3.0 mph + Heading: 47.0 + + ]]> + + -91.594767 + 30.047800 + 66 + + 2002-05-25T18:15:04Z + #track + + -91.594767,30.047800,2.000000 + + + + -23 + + + Longitude: -91.594083 + Latitude: 30.048250 + Altitude: 3.3 ft + Speed: 2.6 mph + Heading: 52.8 + + ]]> + + -91.594083 + 30.048250 + 66 + + 2002-05-25T18:16:14Z + #track + + -91.594083,30.048250,1.000000 + + + + -24 + + + Longitude: -91.593800 + Latitude: 30.048683 + Altitude: 3.3 ft + Speed: 2.6 mph + Heading: 29.5 + + ]]> + + -91.593800 + 30.048683 + 66 + + 2002-05-25T18:17:01Z + #track + + -91.593800,30.048683,1.000000 + + + + -25 + + + Longitude: -91.593850 + Latitude: 30.049350 + Speed: 2.5 mph + Heading: 356.3 + + ]]> + + -91.593850 + 30.049350 + 66 + + 2002-05-25T18:18:07Z + #track + + -91.593850,30.049350,0.000000 + + + + -26 + + + Longitude: -91.593983 + Latitude: 30.050317 + Altitude: 6.6 ft + Speed: 2.3 mph + Heading: 353.2 + + ]]> + + -91.593983 + 30.050317 + 66 + + 2002-05-25T18:19:51Z + #track + + -91.593983,30.050317,2.000000 + + + + -27 + + + Longitude: -91.594117 + Latitude: 30.050783 + Speed: 2.5 mph + Heading: 346.0 + + ]]> + + -91.594117 + 30.050783 + 66 + + 2002-05-25T18:20:39Z + #track + + -91.594117,30.050783,0.000000 + + + + -28 + + + Longitude: -91.594367 + Latitude: 30.051233 + Speed: 2.8 mph + Heading: 334.3 + + ]]> + + -91.594367 + 30.051233 + 66 + + 2002-05-25T18:21:24Z + #track + + -91.594367,30.051233,0.000000 + + + + -29 + + + Longitude: -91.594367 + Latitude: 30.051800 + Speed: 2.7 mph + Heading: 0.0 + + ]]> + + -91.594367 + 30.051800 + 66 + + 2002-05-25T18:22:17Z + #track + + -91.594367,30.051800,0.000000 + + + + -30 + + + Longitude: -91.594667 + Latitude: 30.052217 + Speed: 2.0 mph + Heading: 328.1 + + ]]> + + -91.594667 + 30.052217 + 66 + + 2002-05-25T18:23:18Z + #track + + -91.594667,30.052217,0.000000 + + + + -31 + + + Longitude: -91.594683 + Latitude: 30.053017 + Speed: 2.5 mph + Heading: 359.0 + + ]]> + + -91.594683 + 30.053017 + 66 + + 2002-05-25T18:24:37Z + #track + + -91.594683,30.053017,0.000000 + + + + -32 + + + Longitude: -91.595200 + Latitude: 30.054867 + Altitude: 19.7 ft + Speed: 2.2 mph + Heading: 346.4 + + ]]> + + -91.595200 + 30.054867 + 66 + + 2002-05-25T18:28:13Z + #track + + -91.595200,30.054867,6.000000 + + + + -33 + + + Longitude: -91.594933 + Latitude: 30.053733 + Altitude: 6.6 ft + Speed: 1.4 mph + Heading: 168.5 + + ]]> + + -91.594933 + 30.053733 + 66 + + 2002-05-25T18:31:36Z + #track + + -91.594933,30.053733,2.000000 + + + + -34 + + + Longitude: -91.594783 + Latitude: 30.053183 + Speed: 1.8 mph + Heading: 166.7 + + ]]> + + -91.594783 + 30.053183 + 66 + + 2002-05-25T18:32:56Z + #track + + -91.594783,30.053183,0.000000 + + + + -35 + + + Longitude: -91.594833 + Latitude: 30.052633 + Speed: 2.1 mph + Heading: 184.5 + + ]]> + + -91.594833 + 30.052633 + 66 + + 2002-05-25T18:34:02Z + #track + + -91.594833,30.052633,0.000000 + + + + -36 + + + Longitude: -91.595433 + Latitude: 30.052450 + Speed: 1.1 mph + Heading: 250.6 + + ]]> + + -91.595433 + 30.052450 + 66 + + 2002-05-25T18:36:03Z + #track + + -91.595433,30.052450,0.000000 + + + + -37 + + + Longitude: -91.595967 + Latitude: 30.052483 + Speed: 2.6 mph + Heading: 274.1 + + ]]> + + -91.595967 + 30.052483 + 66 + + 2002-05-25T18:36:48Z + #track + + -91.595967,30.052483,0.000000 + + + + -38 + + + Longitude: -91.596783 + Latitude: 30.052650 + Altitude: 3.3 ft + Speed: 2.8 mph + Heading: 283.3 + + ]]> + + -91.596783 + 30.052650 + 66 + + 2002-05-25T18:37:52Z + #track + + -91.596783,30.052650,1.000000 + + + + -39 + + + Longitude: -91.597850 + Latitude: 30.053133 + Speed: 3.0 mph + Heading: 297.6 + + ]]> + + -91.597850 + 30.053133 + 66 + + 2002-05-25T18:39:18Z + #track + + -91.597850,30.053133,0.000000 + + + + -40 + + + Longitude: -91.597967 + Latitude: 30.053617 + Speed: 2.2 mph + Heading: 348.2 + + ]]> + + -91.597967 + 30.053617 + 66 + + 2002-05-25T18:40:15Z + #track + + -91.597967,30.053617,0.000000 + + + + -41 + + + Longitude: -91.597767 + Latitude: 30.053967 + Altitude: 19.7 ft + Speed: 1.4 mph + Heading: 26.3 + + ]]> + + -91.597767 + 30.053967 + 66 + + 2002-05-25T18:41:25Z + #track + + -91.597767,30.053967,6.000000 + + + + -42 + + + Longitude: -91.598083 + Latitude: 30.053617 + Speed: 1.5 mph + Heading: 218.0 + + ]]> + + -91.598083 + 30.053617 + 66 + + 2002-05-25T18:42:37Z + #track + + -91.598083,30.053617,0.000000 + + + + -43 + + + Longitude: -91.597917 + Latitude: 30.053200 + Speed: 1.3 mph + Heading: 161.0 + + ]]> + + -91.597917 + 30.053200 + 66 + + 2002-05-25T18:44:01Z + #track + + -91.597917,30.053200,0.000000 + + + + -44 + + + Longitude: -91.597517 + Latitude: 30.052817 + Speed: 1.1 mph + Heading: 137.9 + + ]]> + + -91.597517 + 30.052817 + 66 + + 2002-05-25T18:45:53Z + #track + + -91.597517,30.052817,0.000000 + + + + -45 + + + Longitude: -91.596933 + Latitude: 30.052567 + Speed: 2.3 mph + Heading: 116.3 + + ]]> + + -91.596933 + 30.052567 + 66 + + 2002-05-25T18:46:54Z + #track + + -91.596933,30.052567,0.000000 + + + + -46 + + + Longitude: -91.596433 + Latitude: 30.052333 + Speed: 2.6 mph + Heading: 118.4 + + ]]> + + -91.596433 + 30.052333 + 66 + + 2002-05-25T18:47:42Z + #track + + -91.596433,30.052333,0.000000 + + + + -47 + + + Longitude: -91.595683 + Latitude: 30.052250 + Speed: 2.8 mph + Heading: 97.3 + + ]]> + + -91.595683 + 30.052250 + 66 + + 2002-05-25T18:48:41Z + #track + + -91.595683,30.052250,0.000000 + + + + -48 + + + Longitude: -91.595017 + Latitude: 30.052217 + Speed: 2.0 mph + Heading: 93.3 + + ]]> + + -91.595017 + 30.052217 + 66 + + 2002-05-25T18:49:52Z + #track + + -91.595017,30.052217,0.000000 + + + + -49 + + + Longitude: -91.594700 + Latitude: 30.051883 + Speed: 1.9 mph + Heading: 140.6 + + ]]> + + -91.594700 + 30.051883 + 66 + + 2002-05-25T18:50:49Z + #track + + -91.594700,30.051883,0.000000 + + + + -50 + + + Longitude: -91.594400 + Latitude: 30.051050 + Speed: 2.6 mph + Heading: 162.7 + + ]]> + + -91.594400 + 30.051050 + 66 + + 2002-05-25T18:52:14Z + #track + + -91.594400,30.051050,0.000000 + + + + -51 + + + Longitude: -91.594233 + Latitude: 30.050567 + Speed: 3.0 mph + Heading: 163.3 + + ]]> + + -91.594233 + 30.050567 + 66 + + 2002-05-25T18:52:56Z + #track + + -91.594233,30.050567,0.000000 + + + + -52 + + + Longitude: -91.594100 + Latitude: 30.050183 + Speed: 2.4 mph + Heading: 163.3 + + ]]> + + -91.594100 + 30.050183 + 66 + + 2002-05-25T18:53:38Z + #track + + -91.594100,30.050183,0.000000 + + + + -53 + + + Longitude: -91.593717 + Latitude: 30.049100 + Speed: 3.0 mph + Heading: 163.0 + + ]]> + + -91.593717 + 30.049100 + 66 + + 2002-05-25T18:55:11Z + #track + + -91.593717,30.049100,0.000000 + + + + -54 + + + Longitude: -91.594250 + Latitude: 30.048450 + Speed: 2.5 mph + Heading: 215.4 + + ]]> + + -91.594250 + 30.048450 + 66 + + 2002-05-25T18:56:32Z + #track + + -91.594250,30.048450,0.000000 + + + + -55 + + + Longitude: -91.594750 + Latitude: 30.048083 + Speed: 2.7 mph + Heading: 229.7 + + ]]> + + -91.594750 + 30.048083 + 66 + + 2002-05-25T18:57:24Z + #track + + -91.594750,30.048083,0.000000 + + + + -56 + + + Longitude: -91.595450 + Latitude: 30.047500 + Altitude: 23.0 ft + Speed: 2.8 mph + Heading: 226.1 + + ]]> + + -91.595450 + 30.047500 + 66 + + 2002-05-25T18:58:40Z + #track + + -91.595450,30.047500,7.000000 + + + + -57 + + + Longitude: -91.596000 + Latitude: 30.047067 + Speed: 3.3 mph + Heading: 227.7 + + ]]> + + -91.596000 + 30.047067 + 66 + + 2002-05-25T18:59:28Z + #track + + -91.596000,30.047067,0.000000 + + + + -58 + + + Longitude: -91.596600 + Latitude: 30.046633 + Speed: 3.1 mph + Heading: 230.1 + + ]]> + + -91.596600 + 30.046633 + 66 + + 2002-05-25T19:00:22Z + #track + + -91.596600,30.046633,0.000000 + + + + -59 + + + Longitude: -91.597650 + Latitude: 30.046400 + Speed: 3.0 mph + Heading: 255.6 + + ]]> + + -91.597650 + 30.046400 + 66 + + 2002-05-25T19:01:41Z + #track + + -91.597650,30.046400,0.000000 + + + + -60 + + + Longitude: -91.598467 + Latitude: 30.046233 + Speed: 2.7 mph + Heading: 256.7 + + ]]> + + -91.598467 + 30.046233 + 66 + + 2002-05-25T19:02:48Z + #track + + -91.598467,30.046233,0.000000 + + + + -61 + + + Longitude: -91.598967 + Latitude: 30.046317 + Speed: 2.0 mph + Heading: 281.0 + + ]]> + + -91.598967 + 30.046317 + 66 + + 2002-05-25T19:03:43Z + #track + + -91.598967,30.046317,0.000000 + + + + -62 + + + Longitude: -91.599283 + Latitude: 30.046783 + Speed: 2.0 mph + Heading: 329.6 + + ]]> + + -91.599283 + 30.046783 + 66 + + 2002-05-25T19:04:49Z + #track + + -91.599283,30.046783,0.000000 + + + + -63 + + + Longitude: -91.599667 + Latitude: 30.047133 + Speed: 1.8 mph + Heading: 316.5 + + ]]> + + -91.599667 + 30.047133 + 66 + + 2002-05-25T19:05:57Z + #track + + -91.599667,30.047133,0.000000 + + + + + Path + #lineStyle + + 1 + + -91.610350,30.062183,1.000000 + -91.610567,30.062783,0.000000 + -91.608267,30.062700,0.000000 + -91.607383,30.062333,0.000000 + -91.605283,30.061533,0.000000 + -91.599400,30.059783,0.000000 + -91.596683,30.057800,0.000000 + -91.594900,30.055383,0.000000 + -91.592617,30.053883,0.000000 + -91.589750,30.049733,0.000000 + -91.589883,30.049017,0.000000 + -91.592933,30.048800,0.000000 + -91.596450,30.046233,0.000000 + -91.598717,30.045517,0.000000 + -91.600267,30.047300,0.000000 + -91.599633,30.047000,2.000000 + -91.599467,30.046433,0.000000 + -91.598950,30.046200,1.000000 + -91.597733,30.046367,0.000000 + -91.597167,30.046350,0.000000 + -91.596333,30.046783,0.000000 + -91.595200,30.047450,0.000000 + -91.594767,30.047800,2.000000 + -91.594083,30.048250,1.000000 + -91.593800,30.048683,1.000000 + -91.593850,30.049350,0.000000 + -91.593983,30.050317,2.000000 + -91.594117,30.050783,0.000000 + -91.594367,30.051233,0.000000 + -91.594367,30.051800,0.000000 + -91.594667,30.052217,0.000000 + -91.594683,30.053017,0.000000 + -91.595200,30.054867,6.000000 + -91.594933,30.053733,2.000000 + -91.594783,30.053183,0.000000 + -91.594833,30.052633,0.000000 + -91.595433,30.052450,0.000000 + -91.595967,30.052483,0.000000 + -91.596783,30.052650,1.000000 + -91.597850,30.053133,0.000000 + -91.597967,30.053617,0.000000 + -91.597767,30.053967,6.000000 + -91.598083,30.053617,0.000000 + -91.597917,30.053200,0.000000 + -91.597517,30.052817,0.000000 + -91.596933,30.052567,0.000000 + -91.596433,30.052333,0.000000 + -91.595683,30.052250,0.000000 + -91.595017,30.052217,0.000000 + -91.594700,30.051883,0.000000 + -91.594400,30.051050,0.000000 + -91.594233,30.050567,0.000000 + -91.594100,30.050183,0.000000 + -91.593717,30.049100,0.000000 + -91.594250,30.048450,0.000000 + -91.594750,30.048083,0.000000 + -91.595450,30.047500,7.000000 + -91.596000,30.047067,0.000000 + -91.596600,30.046633,0.000000 + -91.597650,30.046400,0.000000 + -91.598467,30.046233,0.000000 + -91.598967,30.046317,0.000000 + -91.599283,30.046783,0.000000 + -91.599667,30.047133,0.000000 + + + + + + + Routes + + BELLEVUE + + Points + + BELLEVUE + + + Longitude: -71.107628 + Latitude: 42.430950 + Altitude: 77.0 ft + Heading: -999.0 + + ]]> + + -71.107628 + 42.430950 + 66 + + 2001-06-02T00:18:15Z + #route + + -71.107628,42.430950,23.469600 + + + + GATE6 + + + Longitude: -71.109236 + Latitude: 42.431240 + Altitude: 87.1 ft + Heading: -999.0 + + ]]> + + -71.109236 + 42.431240 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109236,42.431240,26.561890 + + + + PANTHRCAVE + + + Longitude: -71.109942 + Latitude: 42.434980 + Altitude: 148.6 ft + Heading: -999.0 + + ]]> + + -71.109942 + 42.434980 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109942,42.434980,45.307495 + + + + 6014MEADOW + + + Longitude: -71.113223 + Latitude: 42.436757 + Altitude: 123.4 ft + Heading: -999.0 + + ]]> + + -71.113223 + 42.436757 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.113223,42.436757,37.616943 + + + + 6006 + + + Longitude: -71.114456 + Latitude: 42.439018 + Altitude: 185.0 ft + Heading: -999.0 + + ]]> + + -71.114456 + 42.439018 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.114456,42.439018,56.388000 + + + + 6006BLUE + + + Longitude: -71.114803 + Latitude: 42.438594 + Altitude: 151.0 ft + Heading: -999.0 + + ]]> + + -71.114803 + 42.438594 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.114803,42.438594,46.028564 + + + + 5096 + + + Longitude: -71.116146 + Latitude: 42.438917 + Altitude: 147.1 ft + Heading: -999.0 + + ]]> + + -71.116146 + 42.438917 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.116146,42.438917,44.826904 + + + + 5066 + + + Longitude: -71.119277 + Latitude: 42.438878 + Altitude: 146.3 ft + Heading: -999.0 + + ]]> + + -71.119277 + 42.438878 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.119277,42.438878,44.586548 + + + + 5067 + + + Longitude: -71.119689 + Latitude: 42.439227 + Altitude: 189.0 ft + Heading: -999.0 + + ]]> + + -71.119689 + 42.439227 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.119689,42.439227,57.607200 + + + + 5058ROAD + + + Longitude: -71.120925 + Latitude: 42.439993 + Altitude: 177.0 ft + Heading: -999.0 + + ]]> + + -71.120925 + 42.439993 + 66 + + 2001-06-02T00:18:14Z + #route + + -71.120925,42.439993,53.949600 + + + + 5150TANK + + + Longitude: -71.121676 + Latitude: 42.441727 + Altitude: 221.0 ft + Heading: -999.0 + + ]]> + + -71.121676 + 42.441727 + 66 + + 2001-06-02T00:18:16Z + #route + + -71.121676,42.441727,67.360800 + + + + 5142 + + + Longitude: -71.122044 + Latitude: 42.443904 + Altitude: 166.0 ft + Heading: -999.0 + + ]]> + + -71.122044 + 42.443904 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.122044,42.443904,50.594727 + + + + 5144SUMMIT + + + Longitude: -71.122845 + Latitude: 42.445359 + Altitude: 202.3 ft + Heading: -999.0 + + ]]> + + -71.122845 + 42.445359 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.122845,42.445359,61.649902 + + + + 5156 + + + Longitude: -71.121447 + Latitude: 42.447298 + Altitude: 419.0 ft + Heading: -999.0 + + ]]> + + -71.121447 + 42.447298 + 66 + + 2001-06-02T03:26:58Z + #route + + -71.121447,42.447298,127.711200 + + + + 5148NANEPA + + + Longitude: -71.122320 + Latitude: 42.449765 + Altitude: 393.1 ft + Heading: -999.0 + + ]]> + + -71.122320 + 42.449765 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.122320,42.449765,119.809082 + + + + 5258 + + + Longitude: -71.121746 + Latitude: 42.451442 + Altitude: 244.8 ft + Heading: -999.0 + + ]]> + + -71.121746 + 42.451442 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.121746,42.451442,74.627442 + + + + 5252PURPLE + + + Longitude: -71.121211 + Latitude: 42.453256 + Altitude: 255.9 ft + Heading: -999.0 + + ]]> + + -71.121211 + 42.453256 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.121211,42.453256,77.992066 + + + + 527631 + + + Longitude: -71.119356 + Latitude: 42.456252 + Altitude: 258.2 ft + Heading: -999.0 + + ]]> + + -71.119356 + 42.456252 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.119356,42.456252,78.713135 + + + + 527614 + + + Longitude: -71.119676 + Latitude: 42.456592 + Altitude: 258.2 ft + Heading: -999.0 + + ]]> + + -71.119676 + 42.456592 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.119676,42.456592,78.713135 + + + + 5267OBSTAC + + + Longitude: -71.119845 + Latitude: 42.457388 + Altitude: 242.0 ft + Heading: -999.0 + + ]]> + + -71.119845 + 42.457388 + 66 + + 2001-06-02T03:27:00Z + #route + + -71.119845,42.457388,73.761600 + + + + 5278 + + + Longitude: -71.119135 + Latitude: 42.458148 + Altitude: 224.0 ft + Heading: -999.0 + + ]]> + + -71.119135 + 42.458148 + 66 + + 2001-06-02T03:27:00Z + #route + + -71.119135,42.458148,68.275200 + + + + 5289 + + + Longitude: -71.117693 + Latitude: 42.459377 + Altitude: 210.0 ft + Heading: -999.0 + + ]]> + + -71.117693 + 42.459377 + 66 + + 2001-06-02T03:27:01Z + #route + + -71.117693,42.459377,64.008000 + + + + 5374FIRE + + + Longitude: -71.119828 + Latitude: 42.464183 + Altitude: 173.9 ft + Heading: -999.0 + + ]]> + + -71.119828 + 42.464183 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.119828,42.464183,52.997925 + + + + 5376 + + + Longitude: -71.119399 + Latitude: 42.465650 + Altitude: 185.0 ft + Heading: -999.0 + + ]]> + + -71.119399 + 42.465650 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.119399,42.465650,56.388000 + + + + 5376STREAM + + + Longitude: -71.119328 + Latitude: 42.465913 + Altitude: 211.7 ft + Heading: -999.0 + + ]]> + + -71.119328 + 42.465913 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.119328,42.465913,64.533692 + + + + 6328 + + + Longitude: -71.113574 + Latitude: 42.467110 + Altitude: 176.0 ft + Heading: -999.0 + + ]]> + + -71.113574 + 42.467110 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.113574,42.467110,53.644800 + + + + 635722 + + + Longitude: -71.110067 + Latitude: 42.466459 + Altitude: 160.0 ft + Heading: -999.0 + + ]]> + + -71.110067 + 42.466459 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.110067,42.466459,48.768000 + + + + 635783 + + + Longitude: -71.109410 + Latitude: 42.466557 + Altitude: 161.0 ft + Heading: -999.0 + + ]]> + + -71.109410 + 42.466557 + 66 + + 2001-06-02T03:27:02Z + #route + + -71.109410,42.466557,49.072800 + + + + 6373 + + + Longitude: -71.107117 + Latitude: 42.463495 + Altitude: 205.0 ft + Heading: -999.0 + + ]]> + + -71.107117 + 42.463495 + 66 + + 2001-06-02T03:27:03Z + #route + + -71.107117,42.463495,62.484000 + + + + BEAR HILL + + + Longitude: -71.107360 + Latitude: 42.465687 + Altitude: 288.0 ft + Heading: -999.0 + + ]]> + + -71.107360 + 42.465687 + 66 + + 2001-06-02T03:27:03Z + #route + + -71.107360,42.465687,87.782400 + + + + 6289 + + + Longitude: -71.106170 + Latitude: 42.459986 + Altitude: 239.3 ft + Heading: -999.0 + + ]]> + + -71.106170 + 42.459986 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.106170,42.459986,72.945191 + + + + 6297 + + + Longitude: -71.105116 + Latitude: 42.457616 + Altitude: 239.0 ft + Heading: -999.0 + + ]]> + + -71.105116 + 42.457616 + 66 + + 2001-06-02T03:27:04Z + #route + + -71.105116,42.457616,72.847200 + + + + 6283 + + + Longitude: -71.105206 + Latitude: 42.453845 + Altitude: 218.8 ft + Heading: -999.0 + + ]]> + + -71.105206 + 42.453845 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.105206,42.453845,66.696655 + + + + 6280 + + + Longitude: -71.105413 + Latitude: 42.451430 + Altitude: 188.9 ft + Heading: -999.0 + + ]]> + + -71.105413 + 42.451430 + 66 + + 2001-11-16T23:03:38Z + #route + + -71.105413,42.451430,57.564209 + + + + 6177 + + + Longitude: -71.106158 + Latitude: 42.448448 + Altitude: 204.0 ft + Heading: -999.0 + + ]]> + + -71.106158 + 42.448448 + 66 + + 2001-06-02T03:27:04Z + #route + + -71.106158,42.448448,62.179200 + + + + 6176 + + + Longitude: -71.106624 + Latitude: 42.447804 + Altitude: 205.0 ft + Heading: -999.0 + + ]]> + + -71.106624 + 42.447804 + 66 + + 2001-06-02T03:27:04Z + #route + + -71.106624,42.447804,62.484000 + + + + 6153 + + + Longitude: -71.108882 + Latitude: 42.444773 + Altitude: 206.0 ft + Heading: -999.0 + + ]]> + + -71.108882 + 42.444773 + 66 + + 2001-06-02T03:27:05Z + #route + + -71.108882,42.444773,62.788800 + + + + 6171 + + + Longitude: -71.106301 + Latitude: 42.443592 + Altitude: 182.0 ft + Heading: -999.0 + + ]]> + + -71.106301 + 42.443592 + 66 + + 2001-06-02T03:27:05Z + #route + + -71.106301,42.443592,55.473600 + + + + 6131 + + + Longitude: -71.111441 + Latitude: 42.442981 + Altitude: 210.0 ft + Heading: -999.0 + + ]]> + + -71.111441 + 42.442981 + 66 + + 2001-06-02T03:26:58Z + #route + + -71.111441,42.442981,64.008000 + + + + 6130 + + + Longitude: -71.110975 + Latitude: 42.442196 + Altitude: 210.0 ft + Heading: -999.0 + + ]]> + + -71.110975 + 42.442196 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.110975,42.442196,64.008000 + + + + 6029 + + + Longitude: -71.113220 + Latitude: 42.441754 + Altitude: 185.0 ft + Heading: -999.0 + + ]]> + + -71.113220 + 42.441754 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.113220,42.441754,56.388000 + + + + 6006 + + + Longitude: -71.114456 + Latitude: 42.439018 + Altitude: 185.0 ft + Heading: -999.0 + + ]]> + + -71.114456 + 42.439018 + 66 + + 2001-06-02T03:26:55Z + #route + + -71.114456,42.439018,56.388000 + + + + 6014MEADOW + + + Longitude: -71.113223 + Latitude: 42.436757 + Altitude: 123.4 ft + Heading: -999.0 + + ]]> + + -71.113223 + 42.436757 + 66 + + 2001-11-28T21:05:28Z + #route + + -71.113223,42.436757,37.616943 + + + + PANTHRCAVE + + + Longitude: -71.109942 + Latitude: 42.434980 + Altitude: 148.6 ft + Heading: -999.0 + + ]]> + + -71.109942 + 42.434980 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109942,42.434980,45.307495 + + + + GATE6 + + + Longitude: -71.109236 + Latitude: 42.431240 + Altitude: 87.1 ft + Heading: -999.0 + + ]]> + + -71.109236 + 42.431240 + 66 + + 2001-11-07T23:53:41Z + #route + + -71.109236,42.431240,26.561890 + + + + BELLEVUE + + + Longitude: -71.107628 + Latitude: 42.430950 + Altitude: 77.0 ft + Heading: -999.0 + + ]]> + + -71.107628 + 42.430950 + 66 + + 2001-06-02T00:18:15Z + #route + + -71.107628,42.430950,23.469600 + + + + + Path + #lineStyle + + 1 + + -71.107628,42.430950,23.469600 + -71.109236,42.431240,26.561890 + -71.109942,42.434980,45.307495 + -71.113223,42.436757,37.616943 + -71.114456,42.439018,56.388000 + -71.114803,42.438594,46.028564 + -71.116146,42.438917,44.826904 + -71.119277,42.438878,44.586548 + -71.119689,42.439227,57.607200 + -71.120925,42.439993,53.949600 + -71.121676,42.441727,67.360800 + -71.122044,42.443904,50.594727 + -71.122845,42.445359,61.649902 + -71.121447,42.447298,127.711200 + -71.122320,42.449765,119.809082 + -71.121746,42.451442,74.627442 + -71.121211,42.453256,77.992066 + -71.119356,42.456252,78.713135 + -71.119676,42.456592,78.713135 + -71.119845,42.457388,73.761600 + -71.119135,42.458148,68.275200 + -71.117693,42.459377,64.008000 + -71.119828,42.464183,52.997925 + -71.119399,42.465650,56.388000 + -71.119328,42.465913,64.533692 + -71.113574,42.467110,53.644800 + -71.110067,42.466459,48.768000 + -71.109410,42.466557,49.072800 + -71.107117,42.463495,62.484000 + -71.107360,42.465687,87.782400 + -71.106170,42.459986,72.945191 + -71.105116,42.457616,72.847200 + -71.105206,42.453845,66.696655 + -71.105413,42.451430,57.564209 + -71.106158,42.448448,62.179200 + -71.106624,42.447804,62.484000 + -71.108882,42.444773,62.788800 + -71.106301,42.443592,55.473600 + -71.111441,42.442981,64.008000 + -71.110975,42.442196,64.008000 + -71.113220,42.441754,56.388000 + -71.114456,42.439018,56.388000 + -71.113223,42.436757,37.616943 + -71.109942,42.434980,45.307495 + -71.109236,42.431240,26.561890 + -71.107628,42.430950,23.469600 + + + + + + + diff --git a/reference/earth-gc.kml b/reference/earth-gc.kml new file mode 100644 index 000000000..87c3b9c96 --- /dev/null +++ b/reference/earth-gc.kml @@ -0,0 +1,139 @@ + + + + GPS device + + + + + + + normal + #route_n + + + highlight + #route_h + + + + + + + + + normal + #track_n + + + highlight + #track_h + + + + + + + + + normal + #waypoint_n + + + highlight + #waypoint_h + + + + + Waypoints + + GC7FA4 + + +Points géodésiques du Québec]]> by Sverdrup2]]> Virtual (1.0/1.0)LES COORDONÉES PUBLIÉES NE REPRÉSENTENT PAS LA LOCALISATION D'UNE CACHE +PUBLISHED COORDINATES DO NOT REPRESENT THE LOCALIZATION OF A CACHE

]]> + + 2002-08-15T07:00:00Z + + + -73.000000,46.133333,0.000000 + + + + GCGCA8 + + +Oozy rat in a sanitary zoo]]> by robertlipe]]> Unknown (3.0/2.0)The cache is not at the coordinates above. These coords will get you to the correct park and within 1/2 mile of the cache. The cache is within 35 feet of the trail. It is not handicapped accessible. It is a nice walk in the woods that is practical for all ages. There is no space in the container for trading items. You should bring a writing stick and bug spray is recommended.

]]> +
+ 2003-06-29T07:00:00Z + + + -86.861667,35.921667,0.000000 + +
+ + + Tracks + + + Routes + + + diff --git a/reference/garmin_txt.txt b/reference/garmin_txt.txt new file mode 100644 index 000000000..405581524 --- /dev/null +++ b/reference/garmin_txt.txt @@ -0,0 +1,96 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint 001 Map Line N50 29.556188732 E12 06.325848140 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 002 Map Intersection N50 29.556188732 E12 06.325848140 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 003 Map Intersection N50 29.656610638 E12 06.307823695 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 004 Map Line N50 29.630036652 E12 06.366030984 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 005 Map Line N50 29.630036652 E12 06.366030984 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 006 Map Intersection N50 29.602537304 E12 06.426270045 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint 007 Map Line N50 29.619586095 E12 06.429106481 Symbol Unknown Waypoint 28/03/2006 00:10:37 +Waypoint ED_X Dummy airport (Germany) Airport N51 53.627961650 E12 58.676564991 Symbol & Name Unknown Airport FAC1 CITY1 Germany 28/03/2006 01:38:07 +Waypoint GC_X Dummy airport (Spain) Airport N38 37.919719778 W3 10.443304181 Symbol & Name Unknown Airport FAC2 CITY2 Canary Island 28/03/2006 01:42:01 +Waypoint Jahnstrasse Jahnstrasse 11 User Waypoint N50 29.619998485 E12 06.429000869 Symbol & Description Unknown Flag, Red 31/03/2006 21:48:22 +Waypoint LF_X Dummy airport (France) Airport N46 23.256332763 E3 29.896638617 Symbol & Name Unknown Airport FAC3 CITY3 France 28/03/2006 01:40:32 +Waypoint Liebknechtstrasse Liebknechtstrasse 90 User Waypoint N50 29.630041681 E12 06.366015896 Symbol & Name Unknown Waypoint 31/03/2006 21:49:30 +Waypoint LI_X Dummy airport (Italy) Airport N43 18.873018846 E12 09.693240859 Symbol & Name Unknown Heliport FAC4 CITY4 Italy 28/03/2006 01:43:25 +Waypoint NARVA Start User Waypoint N50 29.556958191 E12 06.326884143 391 m Symbol Unknown Flag, Green 31/03/2006 21:49:26 http://www.narva-light.de Category 15 + + +Header Name Length Course Waypoints Link + +Route ED_X-LF_X 4087 km 232° true 4 waypoints + +Header Waypoint Name Distance Leg Length Course + +Route Waypoint ED_X 0 m +Route Waypoint GC_X 1936 km 1936 km 227° true +Route Waypoint LI_X 3323 km 1388 km 63° true +Route Waypoint LF_X 4087 km 764 km 300° true + +Route NARVA to Jahnstrasse 394 m 46° true 10 waypoints + +Header Waypoint Name Distance Leg Length Course + +Route Waypoint NARVA 0 m +Route Waypoint 001 2 m 2 m 221° true +Route Waypoint 002 2 m 0 m 0° true +Route Waypoint 003 189 m 188 m 353° true +Route Waypoint 004 274 m 85 m 126° true +Route Waypoint Liebknechtstrasse 274 m 0 m 298° true +Route Waypoint 005 274 m 0 m 118° true +Route Waypoint 006 361 m 88 m 126° true +Route Waypoint 007 393 m 32 m 6° true +Route Waypoint Jahnstrasse 394 m 1 m 351° true + + +Header Name Start Time Elapsed Time Length Average Speed Link + +Track ACTIVE LOG 006 01/05/2005 15:02:47 0:33:09 653 m 1.2 kph + +Header Position Time Altitude Depth Leg Length Leg Time Leg Speed Leg Course + +Trackpoint N51 18.776294924 E12 24.789910130 01/05/2005 15:02:47 161 m 0.0 m +Trackpoint N51 18.772960603 E12 24.794909097 01/05/2005 15:03:25 154 m 0.0 m 8 m 0:00:38 0.8 kph 137° true +Trackpoint N51 18.771295957 E12 24.794909097 01/05/2005 15:03:39 148 m 0.0 m 3 m 0:00:14 0.8 kph 180° true +Trackpoint N51 18.769626282 E12 24.798243418 01/05/2005 15:04:16 139 m 0.0 m 5 m 0:00:37 0.5 kph 129° true +Trackpoint N51 18.769626282 E12 24.796573743 01/05/2005 15:05:02 145 m 0.0 m 2 m 0:00:46 0.2 kph 270° true +Trackpoint N51 18.769626282 E12 24.798243418 01/05/2005 15:05:45 134 m 0.0 m 2 m 0:00:43 0.2 kph 90° true +Trackpoint N51 18.766296990 E12 24.799908064 01/05/2005 15:06:44 131 m 0.0 m 6 m 0:00:59 0.4 kph 163° true +Trackpoint N51 18.766296990 E12 24.799908064 01/05/2005 15:07:50 130 m 0.0 m 0 m 0:01:06 0 kph 0° true +Trackpoint N51 18.764627315 E12 24.799908064 01/05/2005 15:08:19 132 m 0.0 m 3 m 0:00:29 0.4 kph 180° true +Trackpoint N51 18.767961636 E12 24.798243418 01/05/2005 15:11:16 144 m 0.0 m 6 m 0:02:57 0.1 kph 343° true +Trackpoint N51 18.774630278 E12 24.806576706 01/05/2005 15:12:34 147 m 0.0 m 16 m 0:01:18 0.7 kph 38° true +Trackpoint N51 18.779629245 E12 24.828242250 01/05/2005 15:13:18 145 m 0.0 m 27 m 0:00:44 2 kph 70° true +Trackpoint N51 18.782963566 E12 24.828242250 01/05/2005 15:13:27 145 m 0.0 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.782963566 E12 24.829906896 01/05/2005 15:13:37 135 m 0.0 m 2 m 0:00:10 0.7 kph 90° true +Trackpoint N51 18.786292858 E12 24.829906896 01/05/2005 15:13:46 135 m 0.0 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.792961501 E12 24.833241217 01/05/2005 15:14:03 136 m 0.0 m 13 m 0:00:17 3 kph 17° true +Trackpoint N51 18.797960468 E12 24.838240184 01/05/2005 15:14:16 135 m 0.0 m 11 m 0:00:13 3 kph 32° true +Trackpoint N51 18.796295822 E12 24.843239151 01/05/2005 15:14:26 139 m 0.0 m 7 m 0:00:10 2 kph 118° true +Trackpoint N51 18.796295822 E12 24.846573472 01/05/2005 15:14:30 139 m 0.0 m 4 m 0:00:04 3 kph 90° true +Trackpoint N51 18.782963566 E12 24.876572303 01/05/2005 15:15:06 141 m 0.0 m 43 m 0:00:36 4 kph 125° true +Trackpoint N51 18.777959570 E12 24.889909588 01/05/2005 15:15:27 140 m 0.0 m 18 m 0:00:21 3 kph 121° true +Trackpoint N51 18.774630278 E12 24.896573201 01/05/2005 15:15:39 140 m 0.0 m 10 m 0:00:12 3 kph 129° true +Trackpoint N51 18.776294924 E12 24.898242876 01/05/2005 15:25:31 152 m 0.0 m 4 m 0:09:52 0.0 kph 32° true +Trackpoint N51 18.776294924 E12 24.898242876 01/05/2005 15:25:40 152 m 0.0 m 0 m 0:00:09 0 kph 0° true +Trackpoint N51 18.777959570 E12 24.896573201 01/05/2005 15:29:18 155 m 0.0 m 4 m 0:03:38 0.1 kph 328° true +Trackpoint N51 18.789627180 E12 24.874907658 01/05/2005 15:30:30 149 m 0.0 m 33 m 0:01:12 2 kph 311° true +Trackpoint N51 18.789627180 E12 24.873243012 01/05/2005 15:30:37 150 m 0.0 m 2 m 0:00:07 1.0 kph 270° true +Trackpoint N51 18.789627180 E12 24.866574369 01/05/2005 15:30:47 151 m 0.0 m 8 m 0:00:10 3 kph 270° true +Trackpoint N51 18.789627180 E12 24.863240048 01/05/2005 15:30:48 151 m 0.0 m 4 m 0:00:01 14 kph 270° true +Trackpoint N51 18.799630143 E12 24.834905863 01/05/2005 15:30:52 150 m 0.0 m 38 m 0:00:04 34 kph 299° true +Trackpoint N51 18.821295686 E12 24.799908064 01/05/2005 15:30:57 150 m 0.0 m 57 m 0:00:05 41 kph 315° true +Trackpoint N51 18.839626908 E12 24.771573879 01/05/2005 15:31:03 150 m 0.0 m 47 m 0:00:06 28 kph 316° true +Trackpoint N51 18.852959163 E12 24.749908336 01/05/2005 15:31:10 150 m 0.0 m 35 m 0:00:07 18 kph 315° true +Trackpoint N51 18.877959028 E12 24.573239610 01/05/2005 15:32:38 143 m 0.0 m 210 m 0:01:28 9 kph 283° true +Trackpoint N51 18.877959028 E12 24.569910318 01/05/2005 15:32:45 141 m 0.0 m 4 m 0:00:07 2 kph 270° true +Trackpoint N51 18.877959028 E12 24.569910318 01/05/2005 15:33:17 143 m 0.0 m 0 m 0:00:32 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.566575997 01/05/2005 15:33:42 139 m 0.0 m 4 m 0:00:25 0.6 kph 270° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:33:54 139 m 0.0 m 6 m 0:00:12 2 kph 270° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:34:04 138 m 0.0 m 0 m 0:00:10 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:34:20 139 m 0.0 m 0 m 0:00:16 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:35:45 144 m 0.0 m 0 m 0:01:25 0 kph 0° true +Trackpoint N51 18.877959028 E12 24.561572000 01/05/2005 15:35:56 145 m 0.0 m 0 m 0:00:11 0 kph 0° true diff --git a/reference/gc/maggeo.gs b/reference/gc/maggeo.gs new file mode 100644 index 000000000..4ca564939 --- /dev/null +++ b/reference/gc/maggeo.gs @@ -0,0 +1,3 @@ +$PMGNGEO,4608.000,N,7300.000,W,0000,F,GC7FA4,Points geodesiques d,Sverdrup2,,Locationless (Reverse) Cache,1508102,1207105,1.0,1.0*3E +$PMGNGEO,3555.300,N,8651.700,W,0000,F,GCGCA8,Oozy rat in a sanita,robertlipe,,Mystery Cache,2906103,0307105,3.0,2.0*4A +$PMGNCMD,END*3D diff --git a/reference/gdb-sample.gdb b/reference/gdb-sample.gdb index ea52c30b9b8de56a1d0c371ab6e9fed670c2f437..0734a34b04ad363c6cf06102f4976e641678c278 100644 GIT binary patch delta 780 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 + - + 3 B93 B93 - Waypoint + Exit Altenburg-Umgehung - abgu (cmt) - abgu (cmt) - abgu (notes) - Golf Course + Altenburg-Umgehung + Altenburg-Umgehung + Exit Elsterberg Piehlerstrasse Piehlerstrasse - Golf Course + Exit Gosel Gosel Gosel - Golf Course + Exit Greiz August-Bebel-Strasse August-Bebel-Strasse - Golf Course + Exit - Jahnstrasse11 + Jahnstrasse Jahnstrasse 11 Jahnstrasse 11 - Golf Course + Exit - Liebknechtstras + Liebknechtstrasse Liebknechtstrasse 90 Liebknechtstrasse 90 - Golf Course + Exit - + 391.000000 + NARVA - Plauen (cmt) - Plauen (cmt) - Wir bei NARVA (notes) - Residence + Start + Start + http://www.narva-light.de + Flag, Green - Völkerschlachtdenkmal - P+R Am Völkerschlachtdenkmal - P+R Am Völkerschlachtdenkmal - http://Voelkerschlachtdenkmal - Waypoint + Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + http://www.leipzig.de + Flag, Red NARVA-Leipzig - + 391.000000 + NARVA - Plauen (cmt) - Plauen (cmt) - Wir bei NARVA (notes) - Residence - - - - 416 - Fahren Sie auf die Luis-Ferdinand-Schönherr-Strasse nach Norden - Waypoint - - - - 417 - Waypoint - - - - 418 - Biegen Sie rechts ab auf die Liebknechtstrasse - Waypoint - - - - 419 - Waypoint + Start + Start + http://www.narva-light.de + Flag, Green - Liebknechtstras + Liebknechtstrasse Liebknechtstrasse 90 Liebknechtstrasse 90 - Golf Course - - - - 420 - Fahren Sie auf die Liebknechtstrasse nach Südosten - Waypoint - - - - 421 - Biegen Sie links ab auf die Jahnstrasse - Waypoint - - - - 422 - Waypoint + Exit - Jahnstrasse11 + Jahnstrasse Jahnstrasse 11 Jahnstrasse 11 - Golf Course - - - - 423 - Fahren Sie auf die Jahnstrasse nach Norden - Waypoint - - - - 424 - Biegen Sie links ab auf die Neundorfer Strasse - Waypoint - - - - 425 - Biegen Sie rechts ab auf die Scharnhorststrasse - Waypoint - - - - 426 - Biegen Sie rechts ab auf die Schminckestrasse - Waypoint - - - - 427 - Biegen Sie links ab auf die Kopernikusstrasse - Waypoint - - - - 428 - Waypoint - - - - 429 - Waypoint - - - - 430 - Waypoint - - - - 431 - Waypoint - - - - 432 - Ordnen Sie sich rechts ein in Richtung Talstrasse - Waypoint - - - - 433 - Waypoint - - - - 434 - Biegen Sie rechts ab auf die Zwoschwitzer Strasse - Waypoint - - - - 435 - Waypoint - - - - 436 - Waypoint - - - - 437 - Waypoint - - - - 438 - Waypoint - - - - 439 - Waypoint - - - - 440 - Waypoint - - - - 441 - Waypoint - - - - 442 - Waypoint - - - - 443 - Waypoint - - - - 444 - Biegen Sie links ab auf die An Der Schöpsdrehe - Waypoint - - - - 445 - Waypoint - - - - 446 - Waypoint - - - - 447 - Biegen Sie rechts ab auf die Elsterberger Strasse - Waypoint - - - - 448 - Waypoint - - - - 449 - Waypoint - - - - 450 - Waypoint - - - - 451 - Waypoint - - - - 452 - Waypoint - - - - 453 - Waypoint - - - - 454 - Biegen Sie rechts ab auf die Robert-Schenker-Strasse - Waypoint - - - - 455 - Biegen Sie links ab auf die Rosa-Luxemburg-Strasse - Waypoint - - - - 456 - Waypoint - - - - 457 - Waypoint - - - - 458 - Waypoint + Exit Elsterberg Piehlerstrasse Piehlerstrasse - Golf Course - - - - 459 - Fahren Sie auf die Piehlerstrasse nach Nordwesten - Waypoint - - - - 460 - Biegen Sie rechts ab auf die Greizer Strasse - Waypoint - - - - 461 - Waypoint - - - - 462 - Waypoint - - - - 463 - Waypoint - - - - 464 - Waypoint - - - - 465 - Waypoint - - - - 466 - Waypoint - - - - 467 - Waypoint - - - - 468 - Waypoint - - - - 469 - Waypoint - - - - 470 - Halten Sie sich rechts in Richtung Carolinenstrasse - Waypoint - - - - 471 - Biegen Sie rechts ab auf die Gartenweg - Waypoint - - - - 472 - Biegen Sie links ab auf die B94 - Waypoint - - - - 473 - Waypoint - - - - 474 - Waypoint - - - - 475 - Waypoint - - - - 476 - Waypoint - - - - 477 - Waypoint + Exit Greiz August-Bebel-Strasse August-Bebel-Strasse - Golf Course - - - - 478 - Fahren Sie auf die August-Bebel-Strasse nach Südosten - Waypoint - - - - 479 - Waypoint - - - - 480 - Waypoint - - - - 481 - Biegen Sie links ab auf die Werdauer Strasse - Waypoint - - - - 482 - Waypoint - - - - 483 - Waypoint - - - - 484 - Halten Sie sich rechts in Richtung Werdauer Strasse - Waypoint - - - - 485 - Waypoint - - - - 486 - Waypoint - - - - 487 - Waypoint - - - - 488 - Waypoint - - - - 489 - Waypoint - - - - 490 - Waypoint - - - - 491 - Waypoint - - - - 492 - Waypoint - - - - 493 - Waypoint - - - - 494 - Waypoint - - - - 495 - Waypoint - - - - 496 - Waypoint - - - - 497 - Waypoint - - - - 498 - Waypoint - - - - 499 - Waypoint - - - - 500 - Waypoint - - - - 501 - Waypoint - - - - 502 - Waypoint - - - - 503 - Halten Sie sich links in Richtung Marienstrasse - Waypoint - - - - 504 - Biegen Sie links ab auf die Uferstrasse - Waypoint - - - - 505 - Waypoint - - - - 506 - Waypoint - - - - 507 - Biegen Sie links ab auf die Querstrasse - Waypoint - - - - 508 - Biegen Sie rechts ab auf die Carthäuserstrasse - Waypoint - - - - 509 - Waypoint - - - - 510 - Waypoint - - - - 511 - Waypoint - - - - 512 - Waypoint - - - - 513 - Halten Sie sich links in Richtung S54 - Waypoint - - - - 514 - Waypoint - - - - 515 - Waypoint - - - - 516 - Waypoint - - - - 517 - Biegen Sie rechts ab auf die Leipziger Strasse - Waypoint - - - - 518 - Biegen Sie rechts ab auf die Leipziger Strasse - Waypoint - - - - 519 - Waypoint - - - - 520 - Biegen Sie links ab auf die Ponitzer Strasse - Waypoint - - - - 521 - Waypoint - - - - 522 - Waypoint - - - - 523 - Waypoint - - - - Gosel - Gosel - Gosel - Golf Course - - - - 524 - Fahren Sie auf die Gosel nach Nordosten - Waypoint - - - - 525 - Waypoint - - - - 526 - Waypoint - - - - 527 - Waypoint - - - - 528 - Biegen Sie rechts ab auf die Gössnitzer Strasse - Waypoint - - - - 529 - Waypoint - - - - 530 - Waypoint - - - - 531 - Biegen Sie links ab auf die Altenburger Strasse - Waypoint - - - - 532 - Waypoint - - - - 533 - Waypoint - - - 3 - B93 - B93 - Waypoint - - - - 534 - Fahren Sie auf die Altenburger Strasse nach Norden - Waypoint - - - - 535 - Waypoint - - - - 536 - Waypoint - - - - 537 - Waypoint - - - - 538 - Waypoint - - - - 539 - Waypoint - - - - 540 - Waypoint - - - - 541 - Waypoint - - - - 542 - Waypoint - - - - 543 - Waypoint - - - - 544 - Waypoint - - - - 545 - Waypoint - - - - 546 - Waypoint - - - - 547 - Waypoint - - - - 548 - Waypoint - - - - 549 - Biegen Sie links ab auf die Hauptstrasse - Waypoint - - - - 550 - Biegen Sie rechts ab auf die K61 - Waypoint - - - - 551 - Waypoint - - - - 552 - Waypoint - - - - 553 - Waypoint - - - - 554 - Waypoint - - - - 555 - Biegen Sie rechts ab auf die Schmöllner Strasse - Waypoint - - - - 556 - Halten Sie sich rechts in Richtung Straße - Waypoint - - - - 557 - Waypoint - - - - Altenburg-Umgehung - abgu (cmt) - abgu (cmt) - abgu (notes) - Golf Course - - - - 558 - Fahren Sie auf die Straße nach Nordosten - Waypoint - - - - 559 - Waypoint - - - - 560 - Waypoint - - - - 561 - Waypoint - - - - 562 - Waypoint - - - - 563 - Waypoint - - - - 564 - Waypoint - - - - 565 - Waypoint - - - - 566 - Waypoint - - - - 567 - Waypoint - - - - 568 - Waypoint - - - - 569 - Waypoint - - - - 570 - Waypoint - - - - 571 - Waypoint - - - - 572 - Waypoint - - - - 573 - Waypoint - - - - 574 - Waypoint - - - - 575 - Waypoint - - - - 576 - Waypoint - - - - 577 - Waypoint - - - - 578 - Waypoint - - - - 579 - Waypoint - - - - 580 - Waypoint - - - - 581 - Waypoint - - - - 582 - Waypoint - - - - 583 - Waypoint - - - - 584 - Waypoint - - - - 585 - Waypoint - - - - 586 - Waypoint - - - - 587 - Waypoint - - - - 588 - Biegen Sie links ab auf die Leipziger Strasse - Waypoint - - - - 589 - Waypoint - - - - 590 - Waypoint - - - - 591 - Waypoint - - - - 592 - Waypoint - - - - 593 - Waypoint - - - - 594 - Waypoint - - - - 595 - Waypoint - - - - 596 - Fahren Sie rechts ab auf die Prinz-Eugen-Strasse - Waypoint - - - - 597 - Waypoint - - - - 598 - Waypoint - - - - 599 - Biegen Sie rechts ab auf die Wolfgang-Heinze-Strasse - Waypoint - - - - 600 - Biegen Sie rechts ab auf die Meusdorfer Strasse - Waypoint - - - - 601 - Biegen Sie rechts ab auf die Arno-Nitzsche-Strasse - Waypoint - - - - 602 - Waypoint - - - - 603 - Waypoint - - - - 604 - Ordnen Sie sich rechts ein in Richtung Strasse Des 18. Oktober - Waypoint - - - - 605 - Waypoint - - - - Völkerschlachtdenkmal - P+R Am Völkerschlachtdenkmal - P+R Am Völkerschlachtdenkmal - http://Voelkerschlachtdenkmal - Waypoint - - - - ACTIVE LOG - - - 360.631714 - - - - 360.631714 - - - - 366.399536 - - - - 366.399536 - - - - 365.918945 - - - - 366.880249 - - - - 366.399536 - - - - 369.764282 - - - - 370.244873 - - - - 370.244873 - - - - 370.244873 - - - - 370.244873 - - - - 371.686890 - - - - 375.051514 - - - - 377.935425 - - - - 385.625977 - - - - 389.951904 - - - - 393.797241 - - - - 393.316528 - - - - 393.316528 - - - - 393.797241 - - - - 395.239136 - - - - 395.719849 - - - - 397.642456 - - - - 398.603760 - - - - 399.084351 - - - - 399.084351 - - - - 398.123169 - - - - 397.642456 - - - - 397.161743 - - - - 396.200562 - - - - 393.797241 - - - - 392.355347 - - - - 391.393799 - - - - 390.913208 - - - - 390.432617 - - - - 390.432617 - - - - 390.432617 - - - - 387.067993 - - - - 387.067993 - - - - 390.913208 - - - - 391.393799 - - - - 391.393799 - - - - 394.758545 - - - - 395.239136 - - - - 395.239136 - - - - 395.239136 - - - - 394.758545 - - - - 397.161743 - - - - 400.045898 - - - - 402.449097 - - - - 401.487793 - - - - 400.526489 - - - - 401.487793 - - - - 402.449097 - - - - 402.449097 - - - - 403.891113 - - - - 405.333008 - - - - 411.100952 - - - - 412.062256 - - - - 413.984863 - - - - 413.984863 - - - - 413.023560 - - - - 413.023560 - - - - 412.542847 - - - - 413.984863 - - - - 413.984863 - - - - 415.426880 - - - - 417.349609 - - - - 418.791504 - - - - 420.233398 - - - - 424.559448 - - - - 426.482056 - - - - 428.404663 - - - - 429.846558 - - - - 428.885376 - - - - 426.001343 - - - - 426.001343 - - - - 423.598022 - - - - 418.310791 - - - - 416.388184 - - - - 411.581665 - - - - 408.217041 - - - - 400.526489 - - - - 399.084351 - - - - 399.565063 - - - - 401.968506 - - - - 406.774902 - - - - 410.620239 - - - - 412.542847 - - - - 413.023560 - - - - 414.946167 - - - - 415.426880 - - - - 417.349609 - - - - 417.830200 - - - - 417.830200 - - - - 417.830200 - - - - 418.310791 - - - - 418.310791 - - - - 419.272217 - - - - 422.636719 - - - - 426.962769 - - - - 428.885376 - - - - 430.807983 - - - - 427.443359 - - - - 424.078735 - - - - 424.078735 - - - - 425.040161 - - - - 425.040161 - - - - 424.078735 - - - - 422.156006 - - - - 420.714111 - - - - 419.272217 - - - - 418.791504 - - - - 418.310791 - - - - 418.791504 - - - - 419.272217 - - - - 422.156006 - - - - 425.040161 - - - - 426.001343 - - - - 428.885376 - - - - 431.288574 - - - - 433.691895 - - - - 434.653320 - - - - 435.133911 - - - - 436.575928 - - - - 438.979126 - - - - 440.901855 - - - - 443.785767 - - - - 444.266479 - - - - 445.708374 - - - - 445.227661 - - - - 445.227661 - - - - 444.266479 - - - - 444.266479 - - - - 445.708374 - - - - 447.150269 - - - - 448.111816 - - - - 449.553711 - - - - 450.034424 - - - - 453.879639 - - - - 454.840820 - - - - 455.802246 - - - - 456.282959 - - - - 455.802246 - - - - 456.282959 - - - - 457.244263 - - - - 458.205566 - - - - 455.802246 - - - - 451.476318 - - - - 448.111816 - - - - 446.189087 - - - - 443.305054 - - - - 440.901855 - - - - 436.095215 - - - - 435.614502 - - - - 434.653320 - - - - 433.691895 - - - - 433.691895 - - - - 435.133911 - - - - 435.614502 - - - - 436.095215 - - - - 436.575928 - - - - 436.095215 - - - - 435.614502 - - - - 435.614502 - - - - 435.614502 - - - - 436.095215 - - - - 435.614502 - - - - 433.691895 - - - - 431.769165 - - - - 429.846558 - - - - 428.885376 - - - - 426.962769 - - - - 425.520752 - - - - 424.078735 - - - - 424.559448 - - - - 424.078735 - - - - 423.117432 - - - - 419.272217 - - - - 409.178345 - - - - 402.929688 - - - - 393.797241 - - - - 389.951904 - - - - 389.471191 - - - - 389.471191 - - - - 389.471191 - - - - 389.471191 - - - - 388.990601 - - - - 388.510010 - - - - 388.029297 - - - - 387.067993 - - - - 384.184082 - - - - 384.184082 - - - - 384.184082 - - - - 382.742065 - - - - 381.780640 - - - - 381.780640 - - - - 380.819458 - - - - 377.935425 - - - - 373.609497 - - - - 368.802979 - - - - 363.996338 - - - - 363.035034 - - - - 359.670410 - - - - 357.747803 - - - - 354.863770 - - - - 351.979858 - - - - 350.057251 - - - - 350.057251 - - - - 349.095825 - - - - 348.615234 - - - - 346.692627 - - - - 345.250610 - - - - 344.770020 - - - - 343.327881 - - - - 341.885986 - - - - 340.444092 - - - - 339.482666 - - - - 338.040771 - - - - 339.002075 - - - - 338.521484 - - - - 338.040771 - - - - 337.079468 - - - - 335.156738 - - - - 332.272827 - - - - 329.869507 - - - - 329.388916 - - - - 326.504883 - - - - 324.101562 - - - - 321.698364 - - - - 320.737061 - - - - 319.295044 - - - - 317.372437 - - - - 315.930420 - - - - 314.007812 - - - - 311.604492 - - - - 307.278564 - - - - 304.394653 - - - - 300.549316 - - - - 298.146118 - - - - 296.223511 - - - - 296.223511 - - - - 295.742676 - - - - 295.742676 - - - - 295.742676 - - - - 294.300781 - - - - 293.339355 - - - - 292.858765 - - - - 292.378174 - - - - 292.378174 - - - - 291.897461 - - - - 289.013550 - - - - 288.052246 - - - - 289.013550 - - - - 288.052246 - - - - 288.532959 - - - - 288.052246 - - - - 287.571411 - - - - 288.052246 - - - - 288.052246 - - - - 287.571411 - - - - 287.090820 - - - - 286.129517 - - - - 285.168213 - - - - 283.726196 - - - - 284.206909 - - - - 284.206909 - - - - 283.245605 - - - - 285.168213 - - - - 282.284302 - - - - 280.842407 - - - - 280.361694 - - - - 280.361694 - - - - 280.842407 - - - - 280.361694 - - - - 280.361694 - - - - 281.322998 - - - - 281.803589 - - - - 281.322998 - - - - 281.322998 - - - - 280.842407 - - - - 280.361694 - - - - 280.361694 - - - - 280.361694 - - - - 279.880859 - - - - 279.400269 - - - - 278.438965 - - - - 278.438965 - - - - 278.438965 - - - - 278.919678 - - - - 278.919678 - - - - 278.919678 - - - - 278.919678 - - - - 279.400269 - - - - 281.803589 - - - - 283.245605 - - - - 283.245605 - - - - 283.245605 - - - - 282.765015 - - - - 286.610229 - - - - 289.494141 - - - - 292.378174 - - - - 294.781372 - - - - 293.339355 - - - - 292.378174 - - - - 291.416748 - - - - 289.494141 - - - - 289.494141 - - - - 289.974854 - - - - 289.013550 - - - - 289.494141 - - - - 289.494141 - - - - 289.974854 - - - - 289.494141 - - - - 288.052246 - - - - 287.571411 - - - - 286.129517 - - - - 283.726196 - - - - 283.245605 - - - - 283.726196 - - - - 284.206909 - - - - 285.168213 - - - - 285.648804 - - - - 285.168213 - - - - 283.245605 - - - - 280.842407 - - - - 278.919678 - - - - 278.438965 - - - - 276.516357 - - - - 275.555054 - - - - 272.671143 - - - - 270.267700 - - - - 269.787109 - - - - 269.787109 - - - - 269.306519 - - - - 270.748413 - - - - 270.748413 - - - - 270.267700 - - - - 269.306519 - - - - 268.825806 - - - - 268.825806 - - - - 268.345093 - - - - 268.345093 - - - - 267.383911 - - - - 267.864502 - - - - 267.864502 - - - - 267.864502 - - - - 268.825806 - - - - 269.306519 - - - - 268.825806 - - - - 268.825806 - - - - 267.864502 - - - - 268.345093 - - - - 268.345093 - - - - 267.864502 - - - - 268.345093 - - - - 270.748413 - - - - 270.748413 - - - - 271.709717 - - - - 267.864502 - - - - 265.941895 - - - - 263.538574 - - - - 264.499878 - - - - 267.383911 - - - - 271.709717 - - - - 270.748413 - - - - 269.306519 - - - - 268.825806 - - - - 270.267700 - - - - 270.748413 - - - - 272.190430 - - - - 274.113037 - - - - 271.709717 - - - - 268.825806 - - - - 268.825806 - - - - 267.864502 - - - - 266.422485 - - - - 265.941895 - - - - 264.499878 - - - - 264.499878 - - - - 264.980591 - - - - 264.019287 - - - - 264.980591 - - - - 264.499878 - - - - 262.577148 - - - - 263.057861 - - - - 264.019287 - - - - 264.980591 - - - - 265.941895 - - - - 268.345093 - - - - 266.903198 - - - - 264.019287 - - - - 264.499878 - - - - 266.903198 - - - - 268.825806 - - - - 272.671143 - - - - 276.035645 - - - - 277.477661 - - - - 278.438965 - - - - 278.438965 - - - - 281.803589 - - - - 281.803589 - - - - 281.803589 - - - - 285.168213 - - - - 289.494141 - - - - 291.897461 - - - - 290.936157 - - - - 290.936157 - - - - 291.416748 - - - - 291.897461 - - - - 291.897461 - - - - 292.858765 - - - - 293.820068 - - - - 292.858765 - - - - 291.897461 - - - - 290.936157 - - - - 291.897461 - - - - 293.339355 - - - - 292.378174 - - - - 291.416748 - - - - 293.339355 - - - - 296.223511 - - - - 299.588013 - - - - 299.588013 - - - - 300.549316 - - - - 301.029907 - - - - 301.991333 - - - - 305.836670 - - - - 310.162476 - - - - 310.643066 - - - - 310.643066 - - - - 310.162476 - - - - 308.720459 - - - - 305.836670 - - - - 305.836670 - - - - 305.836670 - - - - 308.720459 - - - - 315.449829 - - - - 316.891724 - - - - 316.891724 - - - - 316.411011 - - - - 316.891724 - - - - 316.891724 - - - - 315.449829 - - - - 313.046509 - - - - 311.123779 - - - - 311.123779 - - - - 310.643066 - - - - 307.278564 - - - - 308.720459 - - - - 310.162476 - - - - 311.123779 - - - - 312.085205 - - - - 312.565796 - - - - 314.007812 - - - - 315.449829 - - - - 316.411011 - - - - 317.853027 - - - - 318.814331 - - - - 319.295044 - - - - 321.217773 - - - - 324.101562 - - - - 324.582275 - - - - 325.062988 - - - - 326.024170 - - - - 326.024170 - - - - 327.466187 - - - - 328.908325 - - - - 329.869507 - - - - 332.272827 - - - - 336.598877 - - - - 344.289429 - - - - 345.731323 - - - - 345.250610 - - - - 340.924683 - - - - 340.444092 - - - - 339.482666 - - - - 338.521484 - - - - 336.118164 - - - - 335.156738 - - - - 334.676147 - - - - 334.676147 - - - - 334.676147 - - - - 336.118164 - - - - 339.963379 - - - - 344.770020 - - - - 349.095825 - - - - 354.863770 - - - - 360.631714 - - - - 364.476929 - - - - 365.918945 - - - - 366.880249 - - - - 368.322266 - - - - 370.725586 - - - - 372.167480 - - - - 373.609497 - - - - 377.935425 - - - - 379.858032 - - - - 380.819458 - - - - 383.222656 - - - - 388.029297 - - - - 391.874512 - - - - 390.913208 - - - - 387.548584 - - - - 386.106689 - - - - 384.664795 - - - - 380.819458 - - - - 377.935425 - - - - 374.570801 - - - - 371.206299 - - - - 365.438354 - - - - 359.189697 - - - - 358.228394 - - - - 356.786377 - - - - 356.786377 - - - - 356.305786 - - - - 355.344482 - - - - 353.421875 - - - - 351.018433 - - - - 349.576538 - - - - 346.212036 - - - - 343.327881 - - - - 338.040771 - - - - 332.753540 - - - - 328.427612 - - - - 323.620972 - - - - 319.775635 - - - - 316.411011 - - - - 315.449829 - - - - 314.488403 - - - - 314.007812 - - - - 312.565796 - - - - 312.565796 - - - - 312.565796 - - - - 312.085205 - - - - 311.123779 - - - - 310.643066 - - - - 309.681885 - - - - 307.759277 - - - - 306.797852 - - - - 305.355957 - - - - 304.875244 - - - - 304.875244 - - - - 304.394653 - - - - 303.913940 - - - - 303.913940 - - - - 304.394653 - - - - 305.355957 - - - - 305.355957 - - - - 305.355957 - - - - 304.875244 - - - - 306.797852 - - - - 309.681885 - - - - 312.565796 - - - - 312.565796 - - - - 313.046509 - - - - 312.085205 - - - - 309.201172 - - - - 306.797852 - - - - 302.952515 - - - - 301.991333 - - - - 300.068726 - - - - 297.184692 - - - - 294.300781 - - - - 294.300781 - - - - 294.300781 - - - - 293.820068 - - - - 294.300781 - - - - 294.781372 - - - - 295.261963 - - - - 294.781372 - - - - 296.223511 - - - - 296.223511 - - - - 293.339355 - - - - 289.494141 - - - - 290.936157 - - - - 289.974854 - - - - 289.494141 - - - - 289.494141 - - - - 285.168213 - - - - 284.687622 - - - - 285.648804 - - - - 285.648804 - - - - 284.687622 - - - - 283.726196 - - - - 283.245605 - - - - 282.765015 - - - - 282.765015 - - - - 282.284302 - - - - 282.284302 - - - - 281.322998 - - - - 279.880859 - - - - 279.880859 - - - - 279.880859 - - - - 280.361694 - - - - 280.842407 - - - - 280.361694 - - - - 280.361694 - - - - 281.803589 - - - - 282.284302 - - - - 281.803589 - - - - 279.880859 - - - - 278.438965 - - - - 277.958252 - - - - 273.632446 - - - - 272.671143 - - - - 273.151855 - - - - 274.113037 - - - - 272.190430 - - - - 271.229126 - - - - 271.709717 - - - - 271.229126 - - - - 271.229126 - - - - 272.190430 - - - - 270.748413 - - - - 269.787109 - - - - 269.787109 - - - - 269.306519 - - - - 269.306519 - - - - 269.306519 - - - - 274.593750 - - - - 276.035645 - - - - 276.035645 - - - - 275.074463 - - - - 275.555054 - - - - 276.035645 - - - - 276.516357 - - - - 276.997070 - - - - 278.438965 - - - - 278.919678 - - - - 279.400269 - - - - 279.880859 - - - - 277.958252 - - - - 276.035645 - - - - 277.477661 - - - - 277.958252 - - - - 276.516357 - - - - 273.632446 - - - - 270.267700 - - - - 269.787109 - - - - 269.787109 - - - - 271.229126 - - - - 269.787109 - - - - 267.383911 - - - - 265.461304 - - - - 264.980591 - - - - 264.019287 - - - - 263.057861 - - - - 263.538574 - - - - 263.538574 - - - - 262.577148 - - - - 263.538574 - - - - 264.019287 - - - - 264.499878 - - - - 264.499878 - - - - 264.499878 - - - - 264.499878 - - - - 264.499878 - - - - 264.019287 - - - - 264.019287 - - - - 264.019287 - - - - 264.499878 - - - - 263.057861 - - - - 261.615967 - - - - 261.615967 - - - - 262.096558 - - - - 262.096558 - - - - 261.615967 - - - - 261.615967 - - - - 263.538574 - - - - 259.693359 - - - - 257.290039 - - - - 254.886597 - - - - 252.963989 - - - - 251.041382 - - - - 250.080200 - - - - 250.080200 - - - - 251.522095 - - - - 252.963989 - - - - 255.367310 - - - - 256.328735 - - - - 257.290039 - - - - 256.809326 - - - - 254.406006 - - - - 252.963989 - - - - 251.041382 - - - - 249.599487 - - - - 250.080200 - - - - 249.118774 - - - - 248.157593 - - - - 251.522095 - - - - 252.002808 - - - - 251.041382 - - - - 248.638184 - - - - 248.638184 - - - - 247.676758 - - - - 245.273438 - - - - 243.831543 - - - - 240.947632 - - - - 239.024902 - - - - 239.024902 - - - - 237.102295 - - - - 237.582886 - - - - 239.024902 - - - - 242.870239 - - - - 243.831543 - - - - 244.312256 - - - - 244.792847 - - - - 244.792847 - - - - 243.350830 - - - - 244.792847 - - - - 244.792847 - - - - 243.350830 - - - - 245.273438 - - - - 247.196045 - - - - 247.676758 - - - - 248.638184 - - - - 251.041382 - - - - 250.560791 - - - - 246.715454 - - - - 245.754150 - - - - 243.831543 - - - - 240.467041 - - - - 239.986206 - - - - 239.986206 - - - - 243.350830 - - - - 243.831543 - - - - 243.831543 - - - - 242.870239 - - - - 242.870239 - - - - 239.505493 - - - - 235.179688 - - - - 235.660278 - - - - 235.660278 - - - - 236.140991 - - - - 236.621704 - - - - 234.699097 - - - - 231.334351 - - - - 229.411743 - - - - 229.411743 - - - - 231.814941 - - - - 232.776489 - - - - 232.776489 - - - - 232.776489 - - - - 233.257080 - - - - 232.776489 - - - - 232.295776 - - - - 231.814941 - - - - 231.814941 - - - - 231.814941 - - - - 231.814941 - - - - 231.814941 - - - - 231.814941 - - - - 231.814941 - - - - 231.334351 - - - - 231.334351 - - - - 230.853760 - - - - 229.892334 - - - - 229.411743 - - - - 229.411743 - - - - 229.411743 - - - - 229.411743 - - - - 230.373047 - - - - 230.373047 - - - - 229.892334 - - - - 228.450439 - - - - 228.450439 - - - - 227.969727 - - - - 227.969727 - - - - 225.566528 - - - - 224.124512 - - - - 222.682495 - - - - 222.682495 - - - - 222.682495 - - - - 221.240601 - - - - 220.279175 - - - - 220.279175 - - - - 220.759888 - - - - 220.759888 - - - - 221.721191 - - - - 221.721191 - - - - 221.721191 - - - - 221.721191 - - - - 221.721191 - - - - 222.201782 - - - - 223.643799 - - - - 224.124512 - - - - 223.643799 - - - - 223.643799 - - - - 223.643799 - - - - 222.682495 - - - - 223.643799 - - - - 223.643799 - - - - 224.605225 - - - - 225.085938 - - - - 225.085938 - - - - 225.566528 - - - - 226.047119 - - - - 227.008545 - - - - 227.489136 - - - - 227.008545 - - - - 227.008545 - - - - 226.527832 - - - - 227.008545 - - - - 227.489136 - - - - 227.969727 - - - - 227.969727 - - - - 227.969727 - - - - 227.969727 - - - - 227.008545 - - - - 227.008545 - - - - 227.008545 - - - - 226.527832 - - - - 226.047119 - - - - 226.047119 - - - - 228.931152 - - - - 227.489136 - - - - 226.527832 - - - - 226.527832 - - - - 227.008545 - - - - 227.008545 - - - - 225.085938 - - - - 224.605225 - - - - 224.124512 - - - - 223.643799 - - - - 223.643799 - - - - 224.605225 - - - - 227.969727 - - - - 225.085938 - - - - 224.124512 - - - - 224.124512 - - - - 223.163208 - - - - 222.682495 - - - - 222.201782 - - - - 222.201782 - - - - 222.682495 - - - - 222.682495 - - - - 224.124512 - - - - 225.566528 - - - - 224.605225 - - - - 223.163208 - - - - 223.163208 - - - - 221.721191 - - - - 222.201782 - - - - 222.682495 - - - - 222.682495 - - - - 222.201782 - - - - 222.201782 - - - - 222.201782 - - - - 222.201782 - - - - 222.201782 - - - - 219.317993 - - - - 218.837280 - - - - 219.317993 - - - - 219.317993 - - - - 219.317993 - - - - 218.837280 - - - - 218.837280 - - - - 218.837280 - - - - 218.837280 - - - - 218.356567 - - - - 218.356567 - - - - 216.914673 - - - - 215.953247 - - - - 218.356567 - - - - 224.124512 - - - - 225.085938 - - - - 227.008545 - - - - 224.124512 - - - - 221.721191 - - - - 217.875977 - - - - 214.030640 - - - - 214.030640 - - - - 216.914673 - - - - 218.356567 - - - - 218.837280 - - - - 220.279175 - - - - 222.682495 - - - - 225.085938 - - - - 226.047119 - - - - 225.566528 - - - - 225.566528 - - - - 222.682495 - - - - 221.721191 - - - - 215.953247 - - - - 213.550049 - - - - 213.069336 - - - - 211.627441 - - - - 210.185425 - - - - 209.224121 - - - - 208.743408 - - - - 208.262817 - - - - 208.262817 - - - - 208.262817 - - - - 206.340088 - - - - 204.898071 - - - - 202.975464 - - - - 202.494873 - - - - 202.494873 - - - - 204.898071 - - - - 205.378784 - - - - 205.378784 - - - - 205.378784 - - - - 204.898071 - - - - 202.014282 - - - - 199.610840 - - - - 200.091675 - - - - 199.610840 - - - - 199.610840 - - - - 199.610840 - - - - 200.091675 - - - - 202.014282 - - - - 204.417480 - - - - 204.417480 - - - - 205.378784 - - - - 205.378784 - - - - 208.262817 - - - - 207.782104 - - - - 207.782104 - - - - 206.340088 - - - - 203.936890 - - - - 202.014282 - - - - 201.533569 - - - - 201.052856 - - - - 200.091675 - - - - 200.091675 - - - - 201.052856 - - - - 202.014282 - - - - 202.975464 - - - - 202.975464 - - - - 202.975464 - - - - 202.494873 - - - - 202.014282 - - - - 203.936890 - - - - 204.417480 - - - - 203.936890 - - - - 203.456177 - - - - 202.494873 - - - - 200.091675 - - - - 198.168945 - - - - 196.246338 - - - - 196.726929 - - - - 197.207520 - - - - 197.688232 - - - - 197.207520 - - - - 196.726929 - - - - 196.246338 - - - - 195.284912 - - - - 195.765625 - - - - 195.765625 - - - - 196.246338 - - - - 196.246338 - - - - 196.726929 - - - - 198.168945 - - - - 198.168945 - - - - 197.688232 - - - - 196.726929 - - - - 198.168945 - - - - 197.207520 - - - - 197.688232 - - - - 201.533569 - - - - 201.052856 - - - - 205.378784 - - - - 210.185425 - - - - 214.991943 - - - - 209.224121 - - - - 203.456177 - - - - 196.726929 - - - - 194.804321 - - - - 196.246338 - - - - 198.168945 - - - - 198.649536 - - - - 195.765625 - - - - 193.843018 - - - - 192.881714 - - - - 191.439575 - - - - 191.439575 - - - - 190.958984 - - - - 190.478394 - - - - 190.958984 - - - - 191.920288 - - - - 191.439575 - - - - 187.594360 - - - - 183.749023 - - - - 183.749023 - - - - 185.191162 - - - - 186.152466 - - - - 187.113770 - - - - 190.478394 - - - - 192.881714 - - - - 197.688232 - - - - 203.456177 - - - - 206.340088 - - - - 208.743408 - - - - 211.146729 - - - - 214.511230 - - - - 220.759888 - - - - 224.124512 - - - - 224.605225 - - - - 226.047119 - - - - 225.566528 - - - - 225.566528 - - - - 224.605225 - - - - 224.124512 - - - - 224.124512 - - - - 224.124512 - - - - 224.605225 - - - - 225.566528 - - - - 226.527832 - - - - 227.489136 - - - - 227.489136 - - - - 226.047119 - - - - 224.605225 - - - - 222.201782 - - - - 220.759888 - - - - 216.914673 - - - - 210.185425 - - - - 204.898071 - - - - 201.052856 - - - - 198.649536 - - - - 197.688232 - - - - 198.168945 - - - - 200.091675 - - - - 201.533569 - - - - 202.494873 - - - - 203.936890 - - - - 204.417480 - - - - 203.456177 - - - - 201.533569 - - - - 195.284912 - - - - 190.478394 - - - - 184.710571 - - - - 180.384521 - - - - 178.942627 - - - - 178.461914 - - - - 179.423218 - - - - 180.384521 - - - - 182.787842 - - - - 185.191162 - - - - 187.113770 - - - - 188.075073 - - - - 188.555786 - - - - 189.997681 - - - - 190.958984 - - - - 192.401123 - - - - 196.246338 - - - - 198.168945 - - - - 199.610840 - - - - 199.130127 - - - - 198.168945 - - - - 195.765625 - - - - 191.920288 - - - - 186.633179 - - - - 181.345825 - - - - 174.616577 - - - - 170.290649 - - - - 168.848755 - - - - 168.368042 - - - - 169.329468 - - - - 170.290649 - - - - 170.290649 - - - - 169.810059 - - - - 168.848755 - - - - 168.368042 - - - - 166.926025 - - - - 166.445312 - - - - 165.964722 - - - - 165.484131 - - - - 165.003418 - - - - 164.522705 - - - - 165.003418 - - - - 166.926025 - - - - 168.848755 - - - - 169.810059 - - - - 166.445312 - - - - 162.600098 - - - - 160.677490 - - - - 157.793579 - - - - 156.351562 - - - - 154.428955 - - - - 153.467651 - - - - 153.948364 - - - - 153.467651 - - - - 152.506348 - - - - 151.544922 - - - - 151.064209 - - - - 148.180420 - - - - 146.738403 - - - - 146.738403 - - - - 147.699707 - - - - 148.180420 - - - - 148.180420 - - - - 149.622314 - - - - 150.103027 - - - - 150.103027 - - - - 148.661011 - - - - 148.180420 - - - - 147.699707 - - - - 147.218994 - - - - 147.218994 - - - - 146.738403 - - - - 146.257812 - - - - 146.738403 - - - - 147.218994 - - - - 147.699707 - - - - 147.218994 - - - - 147.218994 - - - - 147.218994 - - - - 147.699707 - - - - 147.699707 - - - - 147.699707 - - - - 147.699707 - - - - 148.180420 - - - - 148.180420 - - - - 149.141602 - - - - 149.622314 - - - - 150.103027 - - - - 150.103027 - - - - 150.583618 - - - - 151.064209 - - - - 151.064209 - - - - 151.544922 - - - - 153.467651 - - - - 155.390259 - - - - 157.312866 - - - - 159.235474 - - - - 154.909546 - - - - 152.025757 - - - - 152.986938 - - - - 158.754761 - - - - 162.119507 - - - - 164.522705 - - - - 165.484131 - - - - 166.926025 - - - - 169.329468 - - - - 170.290649 - - - - 170.290649 - - - - 169.329468 - - - - 167.406738 - - - - 165.484131 - - - - 164.522705 - - - - 164.042114 - - - - 163.561523 - - - - 163.561523 - - - - 162.600098 - - - - 161.638916 - - - - 158.274170 - - - - 155.870972 - - - - 154.428955 - - - - 153.467651 - - - - 153.467651 - - - - 153.948364 - - - - 154.428955 - - - - 154.909546 - - - - 153.467651 - - - - 149.141602 - - - - 148.661011 - - - - 147.699707 - - - - 146.257812 - - - - 145.296387 - - - - 144.335205 - - - - 143.854370 - - - - 142.412476 - - - - 140.009155 - - - - 139.528442 - - - - 138.567261 - - - - 140.009155 - - - - 141.451050 - - - - 140.970459 - - - - 140.489868 - - - - 140.009155 - - - - 139.047852 - - - - 139.047852 - - - - 137.605835 - - - - 138.567261 - - - - 139.528442 - - - - 137.605835 - - - - 137.125244 - - - - 137.605835 - - - - 138.567261 - - - - 140.009155 - - - - 140.970459 - - - - 156.351562 - - - - 156.351562 - - - - 157.793579 - - - - 159.235474 - - - - 159.235474 - - - - 159.235474 - - - - 160.196899 - - - - 159.716187 - - - - 159.235474 - - - - 158.274170 - - - - 157.312866 - - - - 158.274170 - - - - 158.754761 - - - - 158.754761 - - - - 157.793579 - - - - 156.351562 - - - - 154.428955 - - - - 152.506348 - - - - 150.103027 - - - - 148.180420 - - - - 145.296387 - - - - 142.893066 - - - - 140.489868 - - - - 139.528442 - - - - 141.451050 - - - - 142.893066 - - - - 145.296387 - - - - 147.218994 - - - - 147.699707 - - - - 147.218994 - - - - 148.180420 - - - - 148.180420 - - - - 149.141602 - - - - 149.622314 - - - - 150.583618 - - - - 150.583618 - - - - 151.064209 - - - - 151.544922 - - - - 152.506348 - - - - 153.467651 - - - - 153.467651 - - - - 153.467651 - - - - 153.467651 - - - - 153.948364 - - - - 155.870972 - - - - 157.312866 - - - - 158.274170 - - - - 158.274170 - - - - 158.754761 - - - - 158.754761 - - - - 157.793579 - - - - 156.832153 - - - - 156.351562 - - - - 154.909546 - - - - 152.506348 - - - - 151.544922 - - - - 149.622314 - - - - 148.180420 - - - - 148.180420 - - - - 147.699707 - - - - 147.218994 - - - - 147.699707 - - - - 147.699707 - - - - 148.180420 - - - - 148.661011 - - - - 149.141602 - - - - 148.661011 - - - - 148.661011 - - - - 149.141602 - - - - 149.622314 - - - - 150.103027 - - - - 149.141602 - - - - 147.699707 - - - - 147.218994 - - - - 146.738403 - - - - 144.815796 - - - - 142.412476 - - - - 141.451050 - - - - 140.009155 - - - - 141.931763 - - - - 142.893066 - - - - 143.373657 - - - - 146.257812 - - - - 148.180420 - - - - 148.180420 - - - - 147.699707 - - - - 146.257812 - - - - 141.451050 - - - - 134.241211 - - - - 127.992554 - - - - 125.589355 - - - - 124.628052 - - - - 126.069946 - - - - 127.511963 - - - - 125.108765 - - - - 126.069946 - - - - 126.550659 - - - - 125.589355 - - - - 125.589355 - - - - 127.031372 - - - - 126.550659 - - - - 125.108765 - - - - 124.147339 - - - - 123.186157 - - - - 122.705444 - - - - 123.666748 - - - - 124.147339 - - - - 124.147339 - - - - 124.147339 - - - - 124.147339 - - - - 122.705444 - - - - 122.224731 - - - - 120.782837 - - - - 120.302124 - - - - 119.821411 - - - - 118.379395 - - - - 117.898804 - - - - 117.418213 - - - - 117.418213 - - - - 116.937500 - - - - 116.456787 - - - - 116.456787 - - - - 116.937500 - - - - 116.937500 - - - - 116.456787 - - - - 116.937500 - - - - 116.937500 - - - - 116.937500 - - - - 115.976196 - - - - 114.534180 - - - - 114.053589 - - - - 113.572998 - - - - 113.572998 - - - - 114.053589 - - - - 113.572998 - - - - 113.572998 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 112.611572 - - - - 112.611572 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 112.130981 - - - - 112.130981 - - - - 112.130981 - - - - 111.650269 - - - - 110.688843 - - - - 110.688843 - - - - 112.130981 - - - - 114.053589 - - - - 114.534180 - - - - 113.092285 - - - - 113.572998 - - - - 115.976196 - - - - 116.937500 - - - - 117.418213 - - - - 115.014893 - - - - 112.130981 - - - - 109.727661 - - - - 109.246948 - - - - 108.285645 - - - - 109.246948 - - - - 109.727661 - - - - 109.246948 - - - - 107.805054 - - - - 105.882446 - - - - 107.805054 - - - - 109.246948 - - - - 108.766235 - - - - 109.727661 - - - - 110.688843 - - - - 112.130981 - - - - 112.130981 - - - - 110.688843 - - - - 109.246948 - - - - 106.363037 - - - - 106.363037 - - - - 110.208252 - - - - 111.169556 - - - - 111.650269 - - - - 112.611572 - - - - 114.053589 - - - - 115.976196 - - - - 116.456787 - - - - 115.976196 - - - - 116.456787 - - - - 116.456787 - - - - 120.782837 - - - - 122.705444 - - - - 119.821411 - - - - 119.821411 - - - - 120.302124 - - - - 119.821411 - - - - 119.821411 - - - - 120.302124 - - - - 121.263550 - - - - 121.744141 - - - - 122.705444 - - - - 123.666748 - - - - 124.147339 - - - - 124.147339 - - - - 125.108765 - - - - 127.031372 - - - - 127.992554 - - - - 128.473389 - - - - 129.434692 - - - - 130.395996 - - - - 129.915283 - - - - 129.434692 - - - - 139.528442 - - - - 138.567261 - - - - 137.605835 - - - - 137.605835 - - - - 136.644653 - - - - 135.683105 - - - - 135.202515 - - - - 137.125244 - - - - 136.644653 - - - - 136.644653 - - - - 135.202515 - - - - 134.241211 - - - - 134.241211 - - - - 134.241211 - - - - 135.683105 - - - - 137.125244 - - - - 139.047852 - - - - 140.009155 - - - - 140.489868 - - - - 140.970459 - - - - 140.970459 - - - - 139.528442 - - - - 137.605835 - - - - 136.163940 - - - - 133.760498 - - - - 139.047852 - - - - 139.528442 - - - - 138.567261 - - - - 139.047852 - - - - 139.528442 - - - - 140.970459 - - - - 139.047852 - - - - 138.567261 - - - - 139.047852 - - - - 141.931763 - - - - 141.931763 - - - - 141.931763 - - - - 141.931763 - - - - 142.412476 - - - - 143.854370 - - - - 146.257812 - - - - 145.296387 - - - - 141.931763 - - - - 141.451050 - - - - 141.451050 - - - - 140.970459 - - - - 139.528442 - - - - 137.125244 - - - - 135.202515 - - - - 134.721924 - - - - 136.644653 - - - - 136.644653 - - - - 135.683105 - - - - 145.777100 - - - - 141.931763 - - - - 137.605835 - - - - 145.777100 - - - - 145.296387 - - - - 146.738403 - - - - 148.661011 - - - - 150.103027 - - - - 142.893066 - - - - 140.970459 - - - - 140.009155 - - - - 142.412476 - - - - 140.970459 - - - - 142.412476 - - - - 144.335205 - - - - 141.931763 - - - - 140.970459 - - - - 140.970459 - - - - 139.528442 - - - - 141.451050 - - - - 143.373657 - - - - 144.815796 - - - - 146.257812 - - - - - - ACTIVE LOG 001 - - - 146.257812 - - - - 145.777100 - - - - 146.738403 - - - - 141.931763 - - - - 141.931763 - - - - 141.451050 - - - - 141.931763 - - - - 142.412476 - - - - 141.931763 - - - - 142.893066 - - - - 142.412476 - - - - 134.241211 - - - - 135.683105 - - - - 136.163940 - - - - 136.644653 - - - - 139.047852 - - - - 142.412476 - - - - - - ACTIVE LOG 002 - - - 136.163940 - - - - 147.699707 - - - - 146.738403 - - - - 154.428955 - - - - 151.064209 - - - - 144.335205 - - - - 142.412476 - - - - 134.241211 - - - - 135.202515 - - - - 135.683105 - - - - 135.202515 - - - - - - ACTIVE LOG 003 - - - 149.622314 - - - - - - ACTIVE LOG 004 - - - 160.677490 - - - - - - ACTIVE LOG 005 - - - 161.158203 - - - - - - ACTIVE LOG 006 - - - 161.158203 - - - - 153.948364 - - - - 148.180420 - - - - 138.567261 - - - - 144.815796 - - - - 133.760498 - - - - 130.876709 - - - - 130.395996 - - - - 131.837891 - - - - 143.854370 - - - - 147.218994 - - - - 145.296387 - - - - 145.296387 - - - - 135.202515 - - - - 134.721924 - - - - 136.163940 - - - - 135.202515 - - - - 138.567261 - - - - 138.567261 - - - - 140.970459 - - - - 139.528442 - - - - 140.489868 - - - - 151.544922 - - - - 152.025757 - - - - 155.390259 - - - - 148.661011 - - - - 149.622314 - - - - 150.583618 - - - - 150.583618 - - - - 149.622314 - - - - 149.622314 - - - - 149.622314 - - - - 149.622314 - - - - 143.373657 - - - - 141.451050 - - - - 143.373657 - - - - 138.567261 - - - - 138.567261 - - - - 138.086548 - - - - 138.567261 - - - - 143.854370 - - - - 144.815796 - - - - - - ACTIVE LOG 007 - - - 150.583618 - - - - 152.025757 - - - - 136.644653 - - - - 133.760498 - - - - 133.760498 - - - - 135.202515 - - - - 131.837891 - - - - 136.644653 - - - - 136.163940 - - - - 134.721924 - - - - 133.760498 - - - - 133.279907 - - - - 131.837891 - - - - 128.954102 - - - - 127.511963 - - - - 126.550659 - - - - 125.589355 - - - - 124.628052 - - - - 123.666748 - - - - 123.186157 - - - - 123.186157 - - - - 120.782837 - - - - 121.263550 - - - - 120.302124 - - - - 118.379395 - - - - 116.937500 - - - - 115.014893 - - - - 114.053589 - - - - 113.092285 - - - - 112.611572 - - - - 112.130981 - - - - 112.611572 - - - - 112.611572 - - - - 113.092285 - - - - 113.572998 - - - - 113.092285 - - - - 112.611572 - - - - 112.611572 - - - - 115.014893 - - - - 115.014893 - - - - 114.053589 - - - - 115.976196 - - - - 115.976196 - - - - 115.976196 - - - - 115.014893 - - - - 114.534180 - - - - 112.130981 - - - - 112.130981 - - - - 109.727661 - - - - 109.727661 - - - - 108.766235 - - - - 110.208252 - - - - 110.208252 - - - - 110.208252 - - - - 111.169556 - - - - 111.650269 - - - - 112.611572 - - - - 112.130981 - - - - 112.130981 - - - - 111.650269 - - - - 110.208252 - - - - 108.766235 - - - - 107.324341 - - - - 106.843628 - - - - 107.324341 - - - - 107.805054 - - - - 107.805054 - - - - 107.324341 - - - - 109.727661 - - - - 110.208252 - - - - 111.169556 - - - - 111.650269 - - - - 113.092285 - - - - 115.014893 - - - - 115.976196 - - - - 114.534180 - - - - 113.092285 - - - - 112.130981 - - - - 112.130981 - - - - 112.611572 - - - - 111.169556 - - - - 109.727661 - - - - 109.246948 - - - - 109.246948 - - - - 110.208252 - - - - 110.208252 - - - - 110.688843 - - - - 111.650269 - - - - 112.130981 - - - - 112.130981 - - - - 112.130981 - - - - 112.611572 - - - - 112.611572 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 113.092285 - - - - 114.053589 - - - - 114.534180 - - - - 115.976196 - - - - 117.418213 - - - - 116.456787 - - - - 116.937500 - - - - 116.937500 - - - - 116.456787 - - - - 116.937500 - - - - 116.937500 - - - - 116.937500 - - - - 117.418213 - - - - 118.379395 - - - - 119.821411 - - - - 120.302124 - - - - 120.302124 - - - - 122.705444 - - - - 122.224731 - - - - 122.224731 - - - - 122.224731 - - - - 122.705444 - - - - 122.705444 - - - - 123.666748 - - - - 124.628052 - - - - 123.186157 - - - - 121.744141 - - - - 121.744141 - - - - 122.705444 - - - - 120.782837 - - - - 121.744141 - - - - 122.705444 - - - - 119.821411 - - - - 122.705444 - - - - 128.473389 - - - - 133.760498 - - - - 138.567261 - - - - 142.893066 - - - - 143.373657 - - - - 142.893066 - - - - 141.451050 - - - - 137.605835 - - - - 136.644653 - - - - 136.644653 - - - - 135.683105 - - - - 135.683105 - - - - 136.644653 - - - - 137.605835 - - - - 138.567261 - - - - 139.528442 - - - - 140.489868 - - - - 141.451050 - - - - 142.412476 - - - - 142.412476 - - - - 142.412476 - - - - 142.412476 - - - - 142.412476 - - - - 143.373657 - - - - 144.335205 - - - - 145.296387 - - - - 145.777100 - - - - 145.777100 - - - - 146.257812 - - - - 146.257812 - - - - 147.218994 - - - - 148.661011 - - - - 149.622314 - - - - 151.544922 - - - - 153.467651 - - - - 154.909546 - - - - 155.870972 - - - - 156.832153 - - - - 158.274170 - - - - 159.716187 - - - - 159.235474 - - - - 158.754761 - - - - 158.274170 - - - - 156.351562 - - - - 156.351562 - - - - 154.909546 - - - - 154.428955 - - - - 153.948364 - - - - 152.986938 - - - - 152.025757 - - - - 151.544922 - - - - 152.025757 - - - - 151.064209 - - - - 149.622314 - - - - 147.218994 - - - - 144.815796 - - - - 143.854370 - - - - 143.373657 - - - - 143.373657 - - - - 143.373657 - - - - 142.412476 - - - - 141.451050 - - - - 139.047852 - - - - 135.202515 - - - - 133.279907 - - - - 133.760498 - - - - 134.241211 - - - - 137.125244 - - - - 140.489868 - - - - 142.893066 - - - - 144.815796 - - - - 146.738403 - - - - 148.180420 - - - - 149.141602 - - - - 150.583618 - - - - 151.064209 - - - - 151.064209 - - - - 151.064209 - - - - 150.103027 - - - - 149.622314 - - - - 150.103027 - - - - 150.583618 - - - - 151.064209 - - - - 151.544922 - - - - 152.025757 - - - - 152.986938 - - - - 154.428955 - - - - 154.428955 - - - - 154.428955 - - - - 154.909546 - - - - 147.699707 - - - - 141.931763 - - - - 139.047852 - - - - 137.125244 - - - - 132.799316 - - - - 130.876709 - - - - 129.915283 - - - - 129.915283 - - - - 129.915283 - - - - 129.915283 - - - - 131.357300 - - - - 132.318604 - - - - 132.799316 - - - - 133.760498 - - - - 134.721924 - - - - 135.683105 - - - - 135.202515 - - - - 135.202515 - - - - 132.318604 - - - - 133.760498 - - - - 135.683105 - - - - 137.125244 - - - - 139.528442 - - - - 140.009155 - - - - 140.970459 - - - - 140.970459 - - - - 141.931763 - - - - 142.412476 - - - - 142.412476 - - - - 142.893066 - - - - 143.373657 - - - - 143.373657 - - - - 143.373657 - - - - 143.854370 - - - - 144.815796 - - - - 147.699707 - - - - 146.738403 - - - - 146.257812 - - - - 145.777100 - - - - 145.296387 - - - - 146.738403 - - - - 147.699707 - - - - 148.661011 - - - - 150.103027 - - - - 152.506348 - - - - 154.909546 - - - - 156.832153 - - - - 157.312866 - - - - 157.793579 - - - - 157.793579 - - - - 158.274170 - - - - 158.274170 - - - - 159.235474 - - - - 162.119507 - - - - 164.042114 - - - - 165.003418 - - - - 165.003418 - - - - 164.042114 - - - - 163.080811 - - - - 162.119507 - - - - 162.600098 - - - - 163.561523 - - - - 162.600098 - - - - 161.638916 - - - - 160.196899 - - - - 156.832153 - - - - 152.506348 - - - - 155.390259 - - - - 156.351562 - - - - 155.870972 - - - - 152.025757 - - - - 149.622314 - - - - 147.699707 - - - - 146.738403 - - - - 146.738403 - - - - 146.257812 - - - - 145.777100 - - - - 144.815796 - - - - 144.335205 - - - - 144.335205 - - - - 144.335205 - - - - 144.335205 - - - - 143.854370 - - - - 144.335205 - - - - 144.335205 - - - - 144.335205 - - - - 144.815796 - - - - 145.296387 - - - - 145.777100 - - - - 146.257812 - - - - 146.738403 - - - - 146.738403 - - - - 146.257812 - - - - 146.738403 - - - - 146.738403 - - - - 146.257812 - - - - 145.777100 - - - - 147.218994 - - - - 147.218994 - - - - 147.218994 - - - - 147.218994 - - - - 147.218994 - - - - 148.180420 - - - - 147.699707 - - - - 148.180420 - - - - 149.622314 - - - - 150.103027 - - - - 150.103027 - - - - 149.622314 - - - - 148.180420 - - - - 148.180420 - - - - 148.661011 - - - - 149.141602 - - - - 149.141602 - - - - 149.141602 - - - - 148.180420 - - - - 149.622314 - - - - 152.986938 - - - - 154.909546 - - - - 156.351562 - - - - 158.274170 - - - - 161.638916 - - - - 164.522705 - - - - 164.042114 - - - - 161.638916 - - - - 159.716187 - - - - 158.754761 - - - - 160.196899 - - - - 161.158203 - - - - 161.638916 - - - - 162.119507 - - - - 162.600098 - - - - 164.042114 - - - - 165.003418 - - - - 165.964722 - - - - 166.926025 - - - - 166.926025 - - - - 165.484131 - - - - 166.926025 - - - - 168.368042 - - - - 170.771362 - - - - 172.213257 - - - - 173.655273 - - - - 176.058594 - - - - 180.384521 - - - - 186.152466 - - - - 189.516968 - - - - 192.401123 - - - - 194.323730 - - - - 194.804321 - - - - 193.843018 - - - - 190.478394 - - - - 187.113770 - - - - 186.633179 - - - - 185.671753 - - - - 184.710571 - - - - 182.787842 - - - - 181.826416 - - - - 179.903809 - - - - 177.500610 - - - - 174.616577 - - - - 172.693970 - - - - 171.732666 - - - - 172.213257 - - - - 174.135864 - - - - 177.020020 - - - - 183.749023 - - - - 189.516968 - - - - 193.843018 - - - - 197.688232 - - - - 200.091675 - - - - 200.572266 - - - - 199.130127 - - - - 197.207520 - - - - 195.284912 - - - - 193.362305 - - - - 191.439575 - - - - 191.439575 - - - - 193.362305 - - - - 197.207520 - - - - 202.014282 - - - - 207.301392 - - - - 214.030640 - - - - 217.395386 - - - - 219.798584 - - - - 222.201782 - - - - 224.124512 - - - - 222.682495 - - - - 221.721191 - - - - 220.759888 - - - - 220.279175 - - - - 220.759888 - - - - 222.201782 - - - - 224.605225 - - - - 226.527832 - - - - 227.008545 - - - - 227.008545 - - - - 226.527832 - - - - 226.527832 - - - - 226.047119 - - - - 225.566528 - - - - 226.047119 - - - - 227.008545 - - - - 227.489136 - - - - 227.969727 - - - - 226.047119 - - - - 222.682495 - - - - 221.240601 - - - - 218.356567 - - - - 216.914673 - - - - 215.472656 - - - - 217.875977 - - - - 220.759888 - - - - 224.605225 - - - - 226.527832 - - - - 229.892334 - - - - 232.295776 - - - - 231.814941 - - - - 231.334351 - - - - 228.931152 - - - - 224.605225 - - - - 220.759888 - - - - 216.914673 - - - - 213.069336 - - - - 206.820679 - - - - 202.494873 - - - - 199.130127 - - - - 196.246338 - - - - 194.323730 - - - - 193.843018 - - - - 193.843018 - - - - 193.362305 - - - - 191.920288 - - - - 189.516968 - - - - 187.113770 - - - - 184.710571 - - - - 182.307129 - - - - 182.307129 - - - - 182.307129 - - - - 182.787842 - - - - 182.787842 - - - - 182.307129 - - - - 182.307129 - - - - 182.787842 - - - - 183.268433 - - - - 184.229858 - - - - 183.749023 - - - - 183.749023 - - - - 183.749023 - - - - 183.749023 - - - - 183.268433 - - - - 183.268433 - - - - 183.268433 - - - - 183.268433 - - - - 183.268433 - - - - 183.749023 - - - - 183.268433 - - - - 183.749023 - - - - 183.749023 - - - - 184.229858 - - - - 184.229858 - - - - 183.749023 - - - - 183.749023 - - - - 184.710571 - - - - 185.191162 - - - - 185.191162 - - - - 185.671753 - - - - 185.191162 - - - - 185.191162 - - - - 185.671753 - - - - 185.671753 - - - - 186.633179 - - - - 186.633179 - - - - 187.113770 - - - - 187.113770 - - - - 188.075073 - - - - 189.516968 - - - - 188.075073 - - - - 188.555786 - - - - 188.555786 - - - - 189.516968 - - - - 189.516968 - - - - 189.997681 - - - - 189.997681 - - - - 189.516968 - - - - 189.997681 - - - - 191.439575 - - - - 192.881714 - - - - 194.323730 - - - - 195.765625 - - - - 195.284912 - - - - 194.804321 - - - - 193.362305 - - - - 192.881714 - - - - 192.881714 - - - - 193.362305 - - - - 192.881714 - - - - 190.958984 - - - - 189.516968 - - - - 189.516968 - - - - 188.555786 - - - - 188.555786 - - - - 188.555786 - - - - 188.555786 - - - - 189.516968 - - - - 190.958984 - - - - 189.516968 - - - - 189.036377 - - - - 188.555786 - - - - 188.555786 - - - - 188.075073 - - - - 188.075073 - - - - 188.555786 - - - - 189.516968 - - - - 189.997681 - - - - 190.478394 - - - - 189.516968 - - - - 189.997681 - - - - 190.478394 - - - - 191.920288 - - - - 191.920288 - - - - 191.920288 - - - - 191.439575 - - - - 191.439575 - - - - 191.439575 - - - - 190.958984 - - - - 191.439575 - - - - 191.439575 - - - - 191.920288 - - - - 192.401123 - - - - 192.401123 - - - - 192.401123 - - - - 191.920288 - - - - 191.439575 - - - - 191.920288 - - - - 193.362305 - - - - 195.284912 - - - - 197.688232 - - - - 198.168945 - - - - 199.130127 - - - - 199.610840 - - - - 199.130127 - - - - 197.688232 - - - - 197.207520 - - - - 197.688232 - - - - 198.168945 - - - - 198.649536 - - - - 198.168945 - - - - 198.168945 - - - - 198.168945 - - - - 197.207520 - - - - 197.207520 - - - - 197.207520 - - - - 197.207520 - - - - 198.168945 - - - - 197.688232 - - - - 197.688232 - - - - 199.130127 - - - - 200.091675 - - - - 201.052856 - - - - 201.052856 - - - - 201.533569 - - - - 200.091675 - - - - 201.052856 - - - - 200.091675 - - - - 199.610840 - - - - 196.726929 - - - - 196.246338 - - - - 195.284912 - - - - 194.804321 - - - - 194.804321 - - - - 195.284912 - - - - 197.688232 - - - - 198.168945 - - - - 197.688232 - - - - 197.688232 - - - - 198.168945 - - - - 198.649536 - - - - 198.649536 - - - - 199.130127 - - - - 199.610840 - - - - 200.091675 - - - - 201.052856 - - - - 201.052856 - - - - 202.494873 - - - - 204.417480 - - - - 206.340088 - - - - 207.782104 - - - - 210.666016 - - - - 213.069336 - - - - 214.511230 - - - - 214.030640 - - - - 213.550049 - - - - 214.511230 - - - - 215.953247 - - - - 217.395386 - - - - 220.759888 - - - - 221.240601 - - - - 221.240601 - - - - 221.240601 - - - - 220.279175 - - - - 219.317993 - - - - 217.875977 - - - - 217.875977 - - - - 218.356567 - - - - 218.356567 - - - - 217.395386 - - - - 218.356567 - - - - 222.682495 - - - - 227.008545 - - - - 231.334351 - - - - 238.544312 - - - - 234.699097 - - - - 231.334351 - - - - 229.892334 - - - - 228.931152 - - - - 228.450439 - - - - 227.969727 - - - - 226.047119 - - - - 222.201782 - - - - 221.240601 - - - - 215.953247 - - - - 214.030640 - - - - 212.108032 - - - - 212.588623 - - - - 211.627441 - - - - 207.782104 - - - - 206.340088 - - - - 204.417480 - - - - 204.417480 - - - - 204.417480 - - - - 204.898071 - - - - 205.859497 - - - - 206.340088 - - - - 207.301392 - - - - 207.782104 - - - - 206.820679 - - - - 206.340088 - - - - 205.378784 - - - - 205.859497 - - - - 207.782104 - - - - - - ACTIVE LOG 008 - - - 203.936890 - - - - 203.936890 - - - - 209.224121 - - - - 221.721191 - - - - - - ACTIVE LOG 009 - - - 218.837280 - - - - 198.649536 - - - - 217.395386 - - - - 209.704834 - - - - 208.262817 - - - - 208.262817 - - - - - - ACTIVE LOG 010 - - - 221.721191 - - - - 219.317993 - - - - 218.837280 - - - - 218.837280 - - - - 218.837280 - - - - 217.875977 - - - - 217.875977 - - - - 217.395386 - - - - 218.356567 - - - - 218.356567 - - - - 217.875977 - - - - 217.875977 - - - - 219.317993 - - - - 220.279175 - - - - 220.279175 - - - - 220.279175 - - - - 220.279175 - - - - 219.317993 - - - - 217.395386 - - - - 216.914673 - - - - 216.433960 - - - - 214.991943 - - - - 215.953247 - - - - 216.433960 - - - - 216.914673 - - - - 216.433960 - - - - 216.914673 - - - - 215.953247 - - - - 215.953247 - - - - 216.914673 - - - - 217.875977 - - - - 218.356567 - - - - 218.837280 - - - - 220.759888 - - - - 222.682495 - - - - 221.240601 - - - - 220.759888 - - - - 219.798584 - - - - 220.279175 - - - - 220.759888 - - - - 221.721191 - - - - 222.682495 - - - - 224.124512 - - - - 227.008545 - - - - 225.566528 - - - - 223.643799 - - - - 223.163208 - - - - 223.163208 - - - - 224.605225 - - - - 225.085938 - - - - 225.085938 - - - - 225.566528 - - - - 225.566528 - - - - 227.489136 - - - - 227.969727 - - - - 228.931152 - - - - 230.373047 - - - - 231.334351 - - - - 231.814941 - - - - 228.931152 - - - - 227.008545 - - - - 225.566528 - - - - 225.566528 - - - - 225.566528 - - - - 226.527832 - - - - 226.527832 - - - - 226.527832 - - - - 227.489136 - - - - 229.892334 - - - - 230.853760 - - - - 229.892334 - - - - 228.931152 - - - - 229.892334 - - - - 229.892334 - - - - 230.853760 - - - - 232.295776 - - - - 233.257080 - - - - 232.776489 - - - - 231.814941 - - - - 230.853760 - - - - 230.853760 - - - - 229.892334 - - - - 229.411743 - - - - 228.450439 - - - - 228.450439 - - - - 228.450439 - - - - 227.008545 - - - - 226.527832 - - - - 226.527832 - - - - 226.527832 - - - - 226.527832 - - - - 227.489136 - - - - 227.969727 - - - - 228.931152 - - - - 229.892334 - - - - 228.931152 - - - - 228.931152 - - - - 228.450439 - - - - 227.969727 - - - - 229.411743 - - - - 230.373047 - - - - 231.334351 - - - - 231.334351 - - - - 231.334351 - - - - 232.776489 - - - - 233.737671 - - - - 234.218384 - - - - 235.660278 - - - - 235.660278 - - - - 237.582886 - - - - 237.582886 - - - - 236.621704 - - - - 236.621704 - - - - 236.621704 - - - - 244.312256 - - - - 241.908936 - - - - 239.505493 - - - - 238.544312 - - - - 236.621704 - - - - 234.699097 - - - - 233.257080 - - - - 233.257080 - - - - 232.776489 - - - - 232.776489 - - - - 233.737671 - - - - 232.776489 - - - - 234.699097 - - - - 236.621704 - - - - 237.582886 - - - - 238.063599 - - - - 238.063599 - - - - 239.024902 - - - - 239.024902 - + Exit + + + + Gosel + Gosel + Gosel + Exit + + + 3 + B93 + B93 + Exit + + + + Altenburg-Umgehung + Altenburg-Umgehung + Altenburg-Umgehung + Exit + + + + Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + P+R Am Völkerschlachtdenkmal + http://www.leipzig.de + Flag, Red + +
+ + ACTIVE LOG 001 + + + 146.257812 + - - 239.505493 - + + 145.777100 + - - 239.986206 - + + 146.738403 + - - 241.428223 - + + 141.931763 + - - 241.428223 - + + 141.931763 + - - 241.428223 - + + 141.451050 + - - 241.428223 - + + 141.931763 + - - 241.428223 - + + 142.412476 + - - 241.428223 - + + 141.931763 + - - 241.428223 - + + 142.893066 + - - 241.908936 - + + 142.412476 + - - 242.870239 - + + 134.241211 + - - 243.350830 - + + 135.683105 + - - 245.273438 - + + 136.163940 + - - 246.234863 - + + 136.644653 + - - 247.196045 - + + 139.047852 + - - 248.157593 - + + 142.412476 + - - 250.560791 - + + + + ACTIVE LOG 002 + + + 136.163940 + - - 252.002808 - + + 147.699707 + - - 253.925415 - + + 146.738403 + - - 252.963989 - + + 154.428955 + - - 252.483398 - + + 151.064209 + - - 251.522095 - + + 144.335205 + - - 250.080200 - + + 142.412476 + - - 249.599487 - + + 134.241211 + - - 249.599487 - + + 135.202515 + - - 250.080200 - + + 135.683105 + - - 250.560791 - + + 135.202515 + - - 249.599487 - + + + + ACTIVE LOG 003 + + + 149.622314 + - - 250.080200 - + + + + ACTIVE LOG 004 + + + 160.677490 + - - 250.560791 - + + + + ACTIVE LOG 005 + + + 161.158203 + - - 250.080200 - + + + + ACTIVE LOG 006 + + + 161.158203 + - - 248.157593 - + + 153.948364 + - - 248.157593 - + + 148.180420 + - - 248.157593 - + + 138.567261 + - - 246.715454 - + + 144.815796 + - - 246.715454 - + + 133.760498 + - - 249.599487 - + + 130.876709 + - - 251.522095 - + + 130.395996 + - - 251.522095 - + + 131.837891 + - - 251.041382 - + + 143.854370 + - - 251.041382 - + + 147.218994 + - - 251.041382 - + + 145.296387 + - - 251.041382 - + + 145.296387 + - - 251.041382 - + + 135.202515 + - - 250.080200 - + + 134.721924 + - - 250.560791 - + + 136.163940 + - - 251.522095 - + + 135.202515 + - - 250.080200 - + + 138.567261 + - - 249.118774 - + + 138.567261 + - - 249.599487 - + + 140.970459 + - - 251.041382 - + + 139.528442 + - - 251.041382 - + + 140.489868 + - - 252.963989 - + + 151.544922 + - - 253.444702 - + + 152.025757 + - - 253.925415 - + + 155.390259 + - - 253.925415 - + + 148.661011 + - - 253.925415 - + + 149.622314 + - - 253.925415 - + + 150.583618 + - - 252.002808 - + + 150.583618 + - - 251.522095 - + + 149.622314 + - - 251.522095 - + + 149.622314 + - - 251.522095 - + + 149.622314 + - - 252.002808 - + + 149.622314 + - - 252.483398 - + + 143.373657 + - - 255.367310 - + + 141.451050 + - - 257.290039 - + + 143.373657 + - - 259.693359 - + + 138.567261 + - - 258.731934 - + + 138.567261 + - - 258.731934 - + + 138.086548 + - - 258.731934 - + + 138.567261 + - - 257.770752 - + + 143.854370 + - - 258.731934 - + + 144.815796 + - - 259.693359 - + + + + ACTIVE LOG 007 + + + 150.583618 + - - 259.212646 - + + 152.025757 + - - 259.212646 - + + 136.644653 + - - 259.693359 - + + 133.760498 + - - 259.212646 - + + 133.760498 + - - 258.251343 - + + 135.202515 + - - 258.251343 - + + 131.837891 + - - 258.251343 - + + 136.644653 + - - 259.212646 - + + 136.163940 + - - 259.693359 - + + 134.721924 + - - 260.173950 - + + 133.760498 + - - 260.654541 - + + 133.279907 + - - 261.135254 - + + 131.837891 + - - 262.096558 - + + 128.954102 + - - 262.577148 - + + 127.511963 + - - 262.577148 - + + 126.550659 + - - 262.577148 - + + 125.589355 + - - 263.538574 - + + 124.628052 + - - 263.057861 - + + 123.666748 + - - 262.577148 - + + 123.186157 + - - 263.538574 - + + 123.186157 + - - 265.461304 - + + 120.782837 + - - 265.941895 - + + 121.263550 + - - 264.980591 - + + 120.302124 + - - 265.461304 - + + 118.379395 + - - 268.825806 - + + 116.937500 + - - 275.074463 - + + 115.014893 + - - 278.919678 - + + 114.053589 + - - 278.919678 - + + 113.092285 + - - 276.997070 - + + 112.611572 + - - 275.555054 - + + 112.130981 + - - 274.113037 - + + 112.611572 + - - 272.671143 - + + 112.611572 + - - 269.787109 - + + 113.092285 + - - 271.229126 - + + 113.572998 + - - 271.709717 - + + 113.092285 + - - 272.190430 - + + 112.611572 + - - 272.671143 - + + 112.611572 + - - 272.190430 - + + 115.014893 + - - 271.709717 - + + 115.014893 + - - 271.229126 - + + 114.053589 + - - 270.748413 - + + 115.976196 + - - 269.787109 - + + 115.976196 + - - 269.306519 - + + 115.976196 + - - 268.825806 - + + 115.014893 + - - 269.306519 - + + 114.534180 + - - 270.267700 - + + 112.130981 + - - 271.229126 - + + 112.130981 + - - 272.190430 - + + 109.727661 + - - 272.190430 - + + 109.727661 + - - 272.190430 - + + 108.766235 + - - 274.113037 - + + 110.208252 + - - 276.035645 - + + 110.208252 + - - 279.400269 - + + 110.208252 + - - 279.400269 - + + 111.169556 + - - 279.400269 - + + 111.650269 + - - 281.322998 - + + 112.611572 + - - 281.803589 - + + 112.130981 + - - 280.361694 - + + 112.130981 + - - 280.842407 - + + 111.650269 + - - 279.400269 - + + 110.208252 + - - 279.400269 - + + 108.766235 + - - 278.919678 - + + 107.324341 + - - 278.919678 - + + 106.843628 + - - 280.842407 - + + 107.324341 + - - 279.880859 - + + 107.805054 + - - 279.400269 - + + 107.805054 + - - 279.400269 - + + 107.324341 + - - 279.400269 - + + 109.727661 + - - 279.400269 - + + 110.208252 + - - 283.726196 - + + 111.169556 + - - 283.245605 - + + 111.650269 + - - 283.726196 - + + 113.092285 + - - 283.245605 - + + 115.014893 + - - 284.206909 - + + 115.976196 + - - 286.129517 - + + 114.534180 + - - 289.013550 - + + 113.092285 + - - 289.494141 - + + 112.130981 + - - 291.897461 - + + 112.130981 + - - 297.665405 - + + 112.611572 + - - 298.626709 - + + 111.169556 + - - 304.875244 - + + 109.727661 + - - 303.913940 - + + 109.246948 + - - 301.510620 - + + 109.246948 + - - 300.549316 - + + 110.208252 + - - 300.549316 - + + 110.208252 + - - 300.068726 - + + 110.688843 + - - 300.068726 - + + 111.650269 + - - 299.107300 - + + 112.130981 + - - 296.223511 - + + 112.130981 + - - 295.261963 - + + 112.130981 + - - 292.858765 - + + 112.611572 + - - 292.378174 - + + 112.611572 + - - 292.858765 - + + 113.092285 + - - 292.858765 - + + 113.092285 + - - 293.339355 - + + 113.092285 + - - 294.781372 - + + 113.092285 + - - 294.300781 - + + 113.092285 + - - 293.820068 - + + 113.092285 + - - 293.820068 - + + 113.092285 + - - 293.820068 - + + 114.053589 + - - 294.300781 - + + 114.534180 + - - 304.875244 - + + 115.976196 + - - 307.759277 - + + 117.418213 + - - 310.643066 - + + 116.456787 + - - 313.527222 - + + 116.937500 + - - 314.969116 - + + 116.937500 + - - 318.333618 - + + 116.456787 + - - 318.814331 - + + 116.937500 + - - 320.737061 - + + 116.937500 + - - 323.620972 - + + 116.937500 + - - 329.869507 - + + 117.418213 + - - 332.753540 - + + 118.379395 + - - 333.234131 - + + 119.821411 + - - 336.118164 - + + 120.302124 + - - 339.482666 - + + 120.302124 + - - 341.405273 - + + 122.705444 + - - 342.366699 - + + 122.224731 + - - 346.692627 - + + 122.224731 + - - 349.576538 - + + 122.224731 + - - 347.653931 - + + 122.705444 + - - 344.289429 - + + 122.705444 + - - 343.808594 - + + 123.666748 + - - 343.808594 - + + 124.628052 + - - 345.731323 - + + 123.186157 + - - 345.731323 - + + 121.744141 + - - 346.212036 - + + 121.744141 + - - 344.770020 - + + 122.705444 + - - 343.808594 - + + 120.782837 + - - 343.327881 - + + 121.744141 + - - 342.847290 - + + 122.705444 + - - 343.808594 - + + 119.821411 + - - 349.095825 - + + 122.705444 + - - 350.537842 - + + 128.473389 + - - 352.460571 - + + 133.760498 + - - 354.863770 - + + 138.567261 + - - 355.825195 - + + 142.893066 + - - 355.825195 - + + 143.373657 + - - 357.267090 - + + 142.893066 + - - 359.189697 - + + 141.451050 + - - 361.593140 - + + 137.605835 + - - 362.554321 - + + 136.644653 + - - 363.996338 - + + 136.644653 + - - 364.957642 - + + 135.683105 + - - 366.399536 - + + 135.683105 + - - 367.841553 - + + 136.644653 + - - 369.764282 - + + 137.605835 + - - 373.128906 - + + 138.567261 + - - 374.570801 - + + 139.528442 + - - 376.012817 - + + 140.489868 + - - 377.935425 - + + 141.451050 + - - 376.974243 - + + 142.412476 + - - 375.051514 - + + 142.412476 + - - 374.570801 - + + 142.412476 + - - 372.648193 - + + 142.412476 + - - 372.167480 - + + 142.412476 + - - 374.090088 - + + 143.373657 + - - 375.532104 - + + 144.335205 + - - 375.532104 - + + 145.296387 + - - 374.570801 - + + 145.777100 + - - 373.128906 - + + 145.777100 + - - 372.167480 - + + 146.257812 + - - 368.802979 - + + 146.257812 + - - 366.880249 - + + 147.218994 + - - 362.554321 - + + 148.661011 + - - 358.708984 - + + 149.622314 + - - 356.305786 - + + 151.544922 + - - 355.825195 - + + 153.467651 + - - 357.747803 - + + 154.909546 + - - 358.228394 - + + 155.870972 + - - 359.670410 - + + 156.832153 + - - 359.670410 - + + 158.274170 + - - 363.515747 - + + 159.716187 + - - 365.438354 - + + 159.235474 + - - 366.880249 - + + 158.754761 + - - 365.438354 - + + 158.274170 + - - 364.476929 - + + 156.351562 + - - 362.073730 - + + 156.351562 + - - 361.593140 - + + 154.909546 + - - 361.593140 - + + 154.428955 + - - 365.918945 - + + 153.948364 + - - 373.609497 - + + 152.986938 + - - 381.780640 - + + 152.025757 + - - 384.664795 - + + 151.544922 + - - 384.184082 - + + 152.025757 + - - 384.184082 - + + 151.064209 + - - 383.222656 - + + 149.622314 + - - 381.780640 - + + 147.218994 + - - 381.300049 - + + 144.815796 + - - 382.261353 - + + 143.854370 + - - 383.222656 - + + 143.373657 + - - 386.587402 - + + 143.373657 + - - 389.951904 - + + 143.373657 + - - 396.681152 - + + 142.412476 + - - 401.487793 - + + 141.451050 + - - 407.736328 - + + 139.047852 + - - 413.984863 - + + 135.202515 + - - 415.426880 - + + 133.279907 + - - 409.178345 - + + 133.760498 + - - 399.565063 - + + 134.241211 + - - 391.874512 - + + 137.125244 + - - 389.471191 - + + 140.489868 + - - 390.913208 - + + 142.893066 + - - 394.758545 - + + 144.815796 + - - 397.161743 - + + 146.738403 + - - 401.007080 - + + 148.180420 + - - 404.371704 - + + 149.141602 + - - 407.255615 - + + 150.583618 + - - 407.255615 - + + 151.064209 + - - 406.294312 - + + 151.064209 + - - 407.255615 - + + 151.064209 + - - 408.697632 - + + 150.103027 + - - 411.100952 - + + 149.622314 + - - 414.465454 - + + 150.103027 + - - 417.830200 - + + 150.583618 + - - 420.714111 - + + 151.064209 + - - 422.636719 - + + 151.544922 + - - 424.078735 - + + 152.025757 + - - 423.598022 - + + 152.986938 + - - 423.598022 - + + 154.428955 + - - 423.117432 - + + 154.428955 + - - 425.040161 - + + 154.428955 + - - 428.404663 - + + 154.909546 + - - 429.365967 - + + 147.699707 + - - 427.443359 - + + 141.931763 + - - 428.404663 - + + 139.047852 + - - 429.846558 - + + 137.125244 + - - 431.288574 - + + 132.799316 + - - 433.211304 - + + 130.876709 + - - 435.133911 - + + 129.915283 + - - 434.653320 - + + 129.915283 + - - 434.172607 - + + 129.915283 + - - 433.691895 - + + 129.915283 + - - 433.211304 - + + 131.357300 + - - 432.250000 - + + 132.318604 + - - 433.211304 - + + 132.799316 + - - 434.653320 - + + 133.760498 + - - 436.095215 - + + 134.721924 + - - 436.575928 - + + 135.683105 + - - 436.575928 - + + 135.202515 + - - 436.095215 - + + 135.202515 + - - 434.653320 - + + 132.318604 + - - 431.769165 - + + 133.760498 + - - 430.327271 - + + 135.683105 + - - 427.443359 - + + 137.125244 + - - 426.962769 - + + 139.528442 + - - 423.598022 - + + 140.009155 + - - 419.272217 - + + 140.970459 + - - 415.907471 - + + 140.970459 + - - 410.620239 - + + 141.931763 + - - 407.736328 - + + 142.412476 + - - 407.255615 - + + 142.412476 + - - 405.333008 - + + 142.893066 + - - 403.410400 - + + 143.373657 + - - 402.449097 - + + 143.373657 + - - 402.929688 - + + 143.373657 + - - 404.371704 - + + 143.854370 + - - 405.333008 - + + 144.815796 + - - 405.333008 - + + 147.699707 + - - 408.697632 - + + 146.738403 + - - 411.581665 - + + 146.257812 + - - 414.465454 - + + 145.777100 + - - 414.946167 - + + 145.296387 + - - 415.907471 - + + 146.738403 + - - 416.388184 - + + 147.699707 + - - 413.984863 - + + 148.661011 + - - 410.620239 - + + 150.103027 + - - 409.659058 - + + 152.506348 + - - 408.697632 - + + 154.909546 + - - 406.294312 - + + 156.832153 + - - 405.333008 - + + 157.312866 + - - 405.333008 - + + 157.793579 + - - 405.333008 - + + 157.793579 + - - 405.333008 - + + 158.274170 + - - 405.333008 - + + 158.274170 + - - 404.852295 - + + 159.235474 + - - 405.333008 - + + 162.119507 + - - 405.813721 - + + 164.042114 + - - 409.659058 - + + 165.003418 + - - 412.542847 - + + 165.003418 + - - 410.620239 - + + 164.042114 + - - 409.178345 - + + 163.080811 + - - 408.697632 - + + 162.119507 + - - 408.697632 - + + 162.600098 + - - 407.736328 - + + 163.561523 + - - 406.294312 - + + 162.600098 + - - 404.852295 - + + 161.638916 + - - 403.410400 - + + 160.196899 + - - 402.929688 - + + 156.832153 + - - 402.449097 - + + 152.506348 + - - 401.487793 - + + 155.390259 + - - 400.526489 - + + 156.351562 + - - 398.603760 - + + 155.870972 + - - 396.681152 - + + 152.025757 + - - 394.758545 - + + 149.622314 + - - 393.797241 - + + 147.699707 + - - 393.316528 - + + 146.738403 + - - 393.316528 - + + 146.738403 + - - 394.758545 - + + 146.257812 + - - 394.277954 - + + 145.777100 + - - 392.835938 - + + 144.815796 + - - 392.355347 - + + 144.335205 + - - 389.951904 - + + 144.335205 + - - 384.664795 - + + 144.335205 + - - 381.780640 - + + 144.335205 + - - 380.338745 - + + 143.854370 + - - 375.051514 - + + 144.335205 + - - 372.648193 - + + 144.335205 + - - 369.283691 - + + 144.335205 + - - 353.902588 - + + 144.815796 + - - 347.653931 - + + 145.296387 + - - 338.521484 - + + 145.777100 + - - 332.753540 - + + 146.257812 + - - 330.350220 - + + 146.738403 + - - 328.427612 - + + 146.738403 + - - 320.256348 - + + 146.257812 + - - 317.853027 - + + 146.738403 + - - 316.891724 - + + 146.738403 + - - 316.411011 - + + 146.257812 + - - 313.046509 - + + 145.777100 + - - 309.681885 - + + 147.218994 + - - 309.201172 - + + 147.218994 + - - 309.201172 - + + 147.218994 + - - 308.239868 - + + 147.218994 + - - 306.317261 - + + 147.218994 + - - 304.875244 - + + 148.180420 + - - 302.471924 - + + 147.699707 + - - 302.952515 - + + 148.180420 + - - 304.394653 - + + 149.622314 + - - 305.836670 - + + 150.103027 + - - 307.759277 - + + 150.103027 + - - 311.123779 - + + 149.622314 + - - 313.527222 - + + 148.180420 + - - 315.930420 - + + 148.180420 + - - 320.256348 - + + 148.661011 + - - 325.543579 - + + 149.141602 + - - 328.427612 - + + 149.141602 + - - 334.195435 - + + 149.141602 + - - 337.079468 - + + 148.180420 + - - 341.405273 - + + 149.622314 + - - 344.770020 - + + 152.986938 + - - 347.653931 - + + 154.909546 + - - 349.095825 - + + 156.351562 + - - 350.537842 - + + 158.274170 + - - 350.537842 - + + 161.638916 + - - 351.018433 - + + 164.522705 + - - 351.979858 - + + 164.042114 + - - 351.018433 - + + 161.638916 + - - 350.057251 - + + 159.716187 + - - 349.576538 - + + 158.754761 + - - 350.057251 - + + 160.196899 + - - 350.057251 - + + 161.158203 + - - 350.057251 - + + 161.638916 + - - 349.576538 - + + 162.119507 + - - 349.095825 - + + 162.600098 + - - 348.615234 - + + 164.042114 + - - 347.653931 - + + 165.003418 + - - 348.615234 - + + 165.964722 + - - 349.095825 - + + 166.926025 + - - 350.057251 - + + 166.926025 + - - 354.383179 - + + 165.484131 + - - 357.267090 - + + 166.926025 + - - 360.631714 - + + 168.368042 + - - 365.438354 - + + 170.771362 + - - 368.322266 - + + 172.213257 + - - 370.244873 - + + 173.655273 + - - 373.128906 - + + 176.058594 + - - 374.570801 - + + 180.384521 + - - 374.570801 - + + 186.152466 + - - 373.609497 - + + 189.516968 + - - 368.322266 - + + 192.401123 + - - 370.725586 - + + 194.323730 + - - 372.167480 - + + 194.804321 + - - 372.648193 - + + 193.843018 + - - 373.609497 - + + 190.478394 + - - 374.570801 - + + 187.113770 + - - 375.051514 - + + 186.633179 + - - 375.532104 - + + 185.671753 + - - 377.935425 - + + 184.710571 + - - 378.416138 - + + 182.787842 + - - 379.858032 - + + 181.826416 + - - 380.338745 - + + 179.903809 + - - 381.780640 - + + 177.500610 + - - 382.261353 - + + 174.616577 + - - 386.106689 - + + 172.693970 + - - 387.067993 - + + 171.732666 + - - 388.029297 - + + 172.213257 + - - 388.029297 - + + 174.135864 + - - 388.510010 - + + 177.020020 + - - 388.029297 - + + 183.749023 + - - 388.510010 - + + 189.516968 + - - 388.510010 - + + 193.843018 + - - 389.471191 - + + 197.688232 + - - 389.951904 - + + 200.091675 + - - 392.355347 - + + 200.572266 + - - 393.797241 - + + 199.130127 + - - 394.758545 - + + 197.207520 + - - 397.161743 - + + 195.284912 + - - 400.045898 - + + 193.362305 + - - 400.526489 - + + 191.439575 + - - 401.487793 - + + 191.439575 + - - 403.410400 - + + 193.362305 + - - 404.371704 - + + 197.207520 + - - 404.371704 - + + 202.014282 + - - 403.891113 - + + 207.301392 + - - 409.178345 - + + 214.030640 + - - 414.465454 - + + 217.395386 + - - 416.868896 - + + 219.798584 + - - 416.868896 - + + 222.201782 + - - 418.310791 - + + 224.124512 + - - 423.117432 - + + 222.682495 + - - 430.327271 - + + 221.721191 + - - 436.095215 - + + 220.759888 + - - 440.901855 - + + 220.279175 + - - 444.266479 - + + 220.759888 + - - 447.150269 - + + 222.201782 + - - 447.150269 - + + 224.605225 + - - 445.227661 - + + 226.527832 + - - 444.266479 - + + 227.008545 + - - 443.305054 - + + 227.008545 + - - 443.305054 - + + 226.527832 + - - 442.824463 - + + 226.527832 + - - 440.901855 - + + 226.047119 + - - 438.979126 - + + 225.566528 + - - 438.979126 - + + 226.047119 + - - 439.940430 - + + 227.008545 + - - 440.901855 - + + 227.489136 + - - 442.824463 - + + 227.969727 + - - 443.785767 - + + 226.047119 + - - 441.863159 - + + 222.682495 + - - 440.901855 - + + 221.240601 + - - 440.421265 - + + 218.356567 + - - 445.708374 - + + 216.914673 + - - 448.111816 - + + 215.472656 + - - 450.515015 - + + 217.875977 + - - 450.515015 - + + 220.759888 + - - 450.034424 - + + 224.605225 + - - 447.630981 - + + 226.527832 + - - 443.785767 - + + 229.892334 + - - 439.459717 - + + 232.295776 + - - 437.056519 - + + 231.814941 + - - 435.614502 - + + 231.334351 + - - 435.614502 - + + 228.931152 + - - 435.614502 - + + 224.605225 + - - 435.614502 - + + 220.759888 + - - 435.133911 - + + 216.914673 + - - 434.653320 - + + 213.069336 + - - 434.653320 - + + 206.820679 + - - 434.172607 - + + 202.494873 + - - 433.691895 - + + 199.130127 + - - 433.691895 - + + 196.246338 + - - 432.730713 - + + 194.323730 + - - 432.250000 - + + 193.843018 + - - 430.807983 - + + 193.843018 + - - 427.443359 - + + 193.362305 + - - 423.598022 - + + 191.920288 + - - 420.714111 - + + 189.516968 + - - 417.349609 - + + 187.113770 + - - 415.907471 - + + 184.710571 + - - 414.465454 - + + 182.307129 + - - 413.504272 - + + 182.307129 + - - 411.100952 - + + 182.307129 + - - 406.294312 - + + 182.787842 + - - 401.487793 - + + 182.787842 + - - 398.123169 - + + 182.307129 + - - 395.239136 - + + 182.307129 + - - 392.835938 - + + 182.787842 + - - 389.951904 - + + 183.268433 + - - 389.471191 - + + 184.229858 + - - 388.990601 - + + 183.749023 + - - 388.990601 - + + 183.749023 + - - 388.510010 - + + 183.749023 + - - 387.548584 - + + 183.749023 + - - 385.625977 - + + 183.268433 + - - 384.184082 - + + 183.268433 + - - 384.184082 - + + 183.268433 + - - 384.664795 - + + 183.268433 + - - 384.664795 - + + 183.268433 + - - 385.145386 - + + 183.749023 + - - 384.664795 - + + 183.268433 + - - 384.184082 - + + 183.749023 + - - 384.184082 - + + 183.749023 + - - 382.742065 - + + 184.229858 + - - 382.261353 - + + 184.229858 + - - 381.780640 - + + 183.749023 + - - 381.780640 - + + 183.749023 + - - 382.261353 - + + 184.710571 + - - 382.742065 - + + 185.191162 + - - 383.222656 - + + 185.191162 + - - 383.703247 - + + 185.671753 + - - 385.625977 - + + 185.191162 + - - 386.587402 - + + 185.191162 + - - 386.587402 - + + 185.671753 + - - 386.587402 - + + 185.671753 + - - 388.029297 - + + 186.633179 + - - 391.393799 - + + 186.633179 + - - 391.393799 - + + 187.113770 + - - 391.393799 - + + 187.113770 + - - 391.393799 - + + 188.075073 + - - 393.316528 - + + 189.516968 + - - 390.432617 - + + 188.075073 + - - 381.300049 - + + 188.555786 + - - 371.206299 - + + 188.555786 + - - 368.322266 - + + 189.516968 + - - 370.725586 - + + 189.516968 + - - 373.128906 - + + 189.997681 + - - 374.570801 - + + 189.997681 + - - 375.532104 - + + 189.516968 + - - 375.532104 - + + 189.997681 + - - 375.532104 - + + 191.439575 + - - 375.532104 - + + 192.881714 + - - 375.051514 - + + 194.323730 + - - 373.609497 - + + 195.765625 + - - 368.802979 - + + 195.284912 + - - 373.128906 - + + 194.804321 + - - 374.570801 - + + 193.362305 + - - 376.974243 - + + 192.881714 + - - 378.416138 - + + 192.881714 + - - 381.780640 - + + 193.362305 + - - 385.145386 - + + 192.881714 + - - 388.990601 - + + 190.958984 + - - 388.510010 - + + 189.516968 + - - 384.184082 - + + 189.516968 + - - 379.858032 - + + 188.555786 + - - 385.625977 - + + 188.555786 + - - 384.184082 - + + 188.555786 + - - 379.858032 - + + 188.555786 + - - 381.300049 - + + 189.516968 + - - 379.377441 - + + 190.958984 + - - 373.609497 - + + 189.516968 + - - 366.399536 - + + 189.036377 + - - 364.476929 - + + 188.555786 + - - 360.151123 - + + 188.555786 + - - 357.747803 - + + 188.075073 + - - 357.267090 - + + 188.075073 + - - 353.421875 - + + 188.555786 + - - 348.134644 - + + 189.516968 + - - 344.770020 - + + 189.997681 + - - 340.444092 - + + 190.478394 + - - 339.963379 - + + 189.516968 + - - 338.521484 - + + 189.997681 + - - 335.637329 - + + 190.478394 + - - 335.156738 - + + 191.920288 + - - 337.560059 - + + 191.920288 + - - 342.366699 - + + 191.920288 + - - 341.885986 - + + 191.439575 + - - 340.924683 - + + 191.439575 + - - 340.924683 - + + 191.439575 + - - 340.924683 - + + 190.958984 + - - 343.327881 - + + 191.439575 + - - 344.770020 - + + 191.439575 + - - 345.250610 - + + 191.920288 + - - 345.731323 - + + 192.401123 + - - 347.653931 - + + 192.401123 + - - 347.173218 - + + 192.401123 + - - 346.692627 - + + 191.920288 + - - 345.250610 - + + 191.439575 + - - 343.808594 - + + 191.920288 + - - 343.327881 - + + 193.362305 + - - 341.405273 - + + 195.284912 + - - 340.924683 - + + 197.688232 + - - 340.924683 - + + 198.168945 + - - 339.482666 - + + 199.130127 + - - 339.482666 - + + 199.610840 + - - 338.040771 - + + 199.130127 + - - 337.079468 - + + 197.688232 + - - 336.118164 - + + 197.207520 + - - 336.118164 - + + 197.688232 + - - 336.118164 - + + 198.168945 + - - 336.118164 - + + 198.649536 + - - 336.118164 - + + 198.168945 + - - 336.598877 - + + 198.168945 + - - 334.195435 - + + 198.168945 + - - 334.195435 - + + 197.207520 + - - 335.156738 - + + 197.207520 + - - 335.156738 - + + 197.207520 + - - 336.598877 - + + 197.207520 + - - 337.079468 - + + 198.168945 + - - 336.598877 - + + 197.688232 + - - 338.040771 - + + 197.688232 + - - 338.521484 - + + 199.130127 + - - 340.444092 - + + 200.091675 + - - 341.405273 - + + 201.052856 + - - 341.885986 - + + 201.052856 + - - 342.847290 - + + 201.533569 + - - 341.405273 - + + 200.091675 + - - 338.521484 - + + 201.052856 + - - 335.637329 - + + 200.091675 + - - 335.637329 - + + 199.610840 + - - 336.118164 - + + 196.726929 + - - 335.637329 - + + 196.246338 + - - 335.156738 - + + 195.284912 + - - 335.156738 - + + 194.804321 + - - 336.118164 - + + 194.804321 + - - 336.598877 - + + 195.284912 + - - 337.079468 - + + 197.688232 + - - 337.079468 - + + 198.168945 + - - 337.079468 - + + 197.688232 + - - 336.118164 - + + 197.688232 + - - 334.676147 - + + 198.168945 + - - 335.156738 - + + 198.649536 + - - 336.118164 - + + 198.649536 + - - 336.598877 - + + 199.130127 + - - 351.979858 - + + 199.610840 + - - 355.344482 - + + 200.091675 + - - 356.786377 - + + 201.052856 + - - 360.151123 - + + 201.052856 + - - 361.593140 - + + 202.494873 + - - 363.035034 - + + 204.417480 + - - 365.438354 - + + 206.340088 + - - 370.244873 - + + 207.782104 + - - 375.051514 - + + 210.666016 + - - 378.896851 - + + 213.069336 + - - 386.106689 - + + 214.511230 + - - 386.587402 - + + 214.030640 + - - 388.029297 - + + 213.550049 + - - 388.029297 - + + 214.511230 + - - 389.951904 - + + 215.953247 + - - 390.913208 - + + 217.395386 + - - 392.835938 - + + 220.759888 + - - 392.835938 - + + 221.240601 + - - 393.316528 - + + 221.240601 + - - 393.316528 - + + 221.240601 + - - 393.316528 - + + 220.279175 + - - 393.797241 - + + 219.317993 + - - 394.277954 - + + 217.875977 + - - 394.277954 - + + 217.875977 + - - 394.758545 - + + 218.356567 + - - 393.316528 - + + 218.356567 + - - 393.316528 - + + 217.395386 + - - 393.797241 - + + 218.356567 + - - 392.355347 - + + 222.682495 + - - 389.471191 - + + 227.008545 + - - 388.510010 - + + 231.334351 + - - 386.587402 - + + 238.544312 + - - 387.067993 - + + 234.699097 + - - 381.300049 - + + 231.334351 + - - 379.377441 - + + 229.892334 + - - 376.493530 - + + 228.931152 + - - 375.532104 - + + 228.450439 + - - 372.167480 - + + 227.969727 + - - 368.322266 - + + 226.047119 + - - 365.918945 - + + 222.201782 + - - 365.918945 - + + 221.240601 + - - 364.476929 - + + 215.953247 + - - 362.554321 - + + 214.030640 + - - 358.708984 - + + 212.108032 + - - 358.228394 - + + 212.588623 + - - 357.267090 - + + 211.627441 + - - 361.593140 - + + 207.782104 + - - 342.847290 - + + 206.340088 + - - 343.327881 - + + 204.417480 + - - 341.885986 - + + 204.417480 + - - 340.924683 - + + 204.417480 + - - 342.847290 - + + 204.898071 + - - 342.366699 - + + 205.859497 + - - 342.847290 - + + 206.340088 + - - 346.692627 - + + 207.301392 + - - 347.653931 - + + 207.782104 + - - 350.057251 - + + 206.820679 + - - 350.537842 - + + 206.340088 + - - 353.421875 - + + 205.378784 + - - 355.344482 - + + 205.859497 + - - 366.399536 - + + 207.782104 + - - 372.167480 - + + + + ACTIVE LOG 008 + + + 203.936890 + - - 372.167480 - + + 203.936890 + - - 368.802979 - + + 209.224121 + - - 368.802979 - + + 221.721191 + - - 368.802979 - + + + + ACTIVE LOG 009 + + + 218.837280 + - - 368.322266 - + + 198.649536 + - - 371.206299 - + + 217.395386 + - - 371.206299 - + + 209.704834 + - - 370.244873 - + + 208.262817 + - - 371.206299 - + + 208.262817 + diff --git a/reference/gdb-sample2.gdb b/reference/gdb-sample2.gdb new file mode 100644 index 0000000000000000000000000000000000000000..670d0c59ac821a62b1d5c313838b9b6be08b665a GIT binary patch literal 6314 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 B8D#(f literal 0 HcmV?d00001 diff --git a/reference/geonet-sample.gpx b/reference/geonet-sample.gpx new file mode 100644 index 000000000..67c7af66a --- /dev/null +++ b/reference/geonet-sample.gpx @@ -0,0 +1,55 @@ + + + + + + PLAUEN + Plauen + Plauen + + + PLAUEN + Plauen + Plauen + + + PLAUEN STADTKREIS + Stadtkreis Plauen + Stadtkreis Plauen + + + PLAUENERSTADTWALD + Plauener Stadtwald + Plauener Stadtwald + + + ZSCHOPAU + Zschopau + Zschopau + + + ZSCHOPAU + Zschopau + Zschopau + + + ZSCHOPEL + Zschöpel + Zschöpel + + + ZSCHOPENBERG + Zschopen-Berg + Zschopen-Berg + + + ZSCHOPENTHAL + Zschopenthal + Zschopenthal + + diff --git a/reference/geonet-sample.txt b/reference/geonet-sample.txt new file mode 100644 index 000000000..d6c89798e --- /dev/null +++ b/reference/geonet-sample.txt @@ -0,0 +1,10 @@ +RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE +1 -1843626 -2549662 51.0166667 13.7166667 510100 134300 VS05 NM33-01 P PPLX GM 13 N PLAUEN Plauen Plauen 1994-01-08 +1 -1843625 -2549661 50.5 12.1333333 503000 120800 TR99 NM33-04 P PPL 3 GM 13 N PLAUEN Plauen Plauen 2002-05-02 +1 -1843628 -2549664 50.5 12.1333333 503000 120800 TR99 NM33-04 A ADM3 GM 13 Chemnitz V PLAUEN STADTKREIS Stadtkreis Plauen Stadtkreis Plauen 1998-04-28 +1 -1843629 -2549666 50.5333333 12.1333333 503200 120800 TS90 NM33-04 V FRST GM 13 N PLAUENERSTADTWALD Plauener Stadtwald Plauener Stadtwald 1998-05-12 +1 -1893314 -2603706 51.1333333 13.05 510800 130300 US66 NM33-01 H STM GM 13 N ZSCHOPAU Zschopau Zschopau 1994-01-08 +1 -1893313 -2603705 50.75 13.0666667 504500 130400 US62 NM33-04 P PPL 4 GM 13 N ZSCHOPAU Zschopau Zschopau 2002-05-02 +1 -1893316 -2603708 50.8666667 12.4166667 505200 122500 US13 NM33-04 P PPL GM 15 N ZSCHOPEL Zschöpel Zschopel 1998-05-15 +1 -1893317 -2603709 50.7333333 13.0666667 504400 130400 US62 NM33-04 T HLL GM 13 N ZSCHOPENBERG Zschopen-Berg Zschopen-Berg 1994-01-08 +1 -1893318 -2603710 50.7666667 13.1 504600 130600 US62 NM33-04 P PPL GM 13 N ZSCHOPENTHAL Zschopenthal Zschopenthal 1994-01-08 diff --git a/reference/gn-targets.gpx b/reference/gn-targets.gpx new file mode 100644 index 000000000..556a6e3dd --- /dev/null +++ b/reference/gn-targets.gpx @@ -0,0 +1,34 @@ + + + + + + 44.000000 + + 5066 + 5066 + 5066 + Scenic Area + + + 57.000000 + + 5067 + 5067 + 5067 + Traditional Cache + + + 44.000000 + + 5096 + 5096 + 5096 + Residence + + diff --git a/reference/gn-targets.pdb b/reference/gn-targets.pdb new file mode 100644 index 0000000000000000000000000000000000000000..188a5bd044db438346d263ae09e1f3fff539bf93 GIT binary patch literal 586 zcmZ=y&G*Yp&PY`VNi0fFEh%O|2OJEH`;WOK?LSucA0oxN9!O_^*e;GCj_yGH2Nen+ zQp^ktjCD>26{LamAs{Woz`(@jcu+wWC|w_#mzJ56ngUS?B;6B>6@p6=OEUBGz+%pc zKxe>Z85lhCN>Yo8QMi16da3E6QOFtGE>V7@-y>Fp#1Q}N@OmQNrQyR$i&RT z%Er#Y$;HjX%g4_Ta+W@Ggoy{E0;~Ol93W4JaXo_!11p0VkmP2+$N&saFkob0WG?`U zUw2?+`2W9yAuK@>D9)&7YG7stG9!HT7mykDH9%2Ipc&>2Qb5&A3~WF%*dRtQV45KX slwtA#nqdxhhbj-y4435Google Local \ No newline at end of file diff --git a/reference/hiketech.gpx b/reference/hiketech.gpx new file mode 100644 index 000000000..8548aef14 --- /dev/null +++ b/reference/hiketech.gpx @@ -0,0 +1,734 @@ + + + + + + 5066 + 5066 + 5066 + Crossing + + + 5067 + 5067 + 5067 + Dot + + + 5096 + 5096 + 5096 + Dot + + + 5142 + 5142 + 5142 + Dot + + + 5156 + 5156 + 5156 + Dot + + + 5224 + 5224 + 5224 + Dot + + + 5229 + 5229 + 5229 + Dot + + + 5237 + 5237 + 5237 + Dot + + + 5254 + 5254 + 5254 + Dot + + + 5258 + 5258 + 5258 + Dot + + + 5264 + 5264 + 5264 + Dot + + + 526708 + 526708 + 526708 + Dot + + + 526750 + 526750 + 526750 + Dot + + + 527614 + 527614 + 527614 + Dot + + + 527631 + 527631 + 527631 + Dot + + + 5278 + 5278 + 5278 + Dot + + + 5289 + 5289 + 5289 + Dot + + + 5374FIRE + 5374FIRE + 5374FIRE + Dot + + + 5376 + 5376 + 5376 + Dot + + + 6006 + 6006 + 6006 + Dot + + + 6006BLUE + 6006BLUE + 6006BLUE + Dot + + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + + + 6029 + 6029 + 6029 + Dot + + + 6053 + 6053 + 6053 + Dot + + + 6066 + 6066 + 6066 + Dot + + + 6067 + 6067 + 6067 + Dot + + + 6071 + 6071 + 6071 + Dot + + + 6073 + 6073 + 6073 + Dot + + + 6084 + 6084 + 6084 + Dot + + + 6130 + 6130 + 6130 + Dot + + + 6131 + 6131 + 6131 + Dot + + + 6153 + 6153 + 6153 + Dot + + + 6171 + 6171 + 6171 + Dot + + + 6176 + 6176 + 6176 + Dot + + + 6177 + 6177 + 6177 + Dot + + + 6272 + 6272 + 6272 + Dot + + + 6272 + 6272 + 6272 + Dot + + + 6278 + 6278 + 6278 + Dot + + + 6280 + 6280 + 6280 + Dot + + + 6283 + 6283 + 6283 + Dot + + + 6289 + 6289 + 6289 + Dot + + + 6297 + 6297 + 6297 + Dot + + + 6328 + 6328 + 6328 + Dot + + + 6354 + 6354 + 6354 + Dot + + + 635722 + 635722 + 635722 + Dot + + + 635783 + 635783 + 635783 + Dot + + + 6373 + 6373 + 6373 + Dot + + + 6634 + 6634 + 6634 + Dot + + + 6979 + 6979 + 6979 + Dot + + + 6997 + 6997 + 6997 + Dot + + + BEAR HILL + BEAR HILL + BEAR HILL + Tall Tower + + + BELLEVUE + BELLEVUE + BELLEVUE + Parking Area + + + 6016 + 6016 + 6016 + Waypoint + + + 5236BRIDGE + 5236BRIDGE + 5236BRIDGE + Bridge + + + 5376BRIDGE + 5376BRIDGE + 5376BRIDGE + Bridge + + + 6181CROSS + 6181CROSS + 6181CROSS + Crossing + + + 6042CROSS + 6042CROSS + 6042CROSS + Crossing + + + DARKHOLLPO + DARKHOLLPO + DARKHOLLPO + Fishing Area + + + 6121DEAD + 6121DEAD + 6121DEAD + Danger Area + + + 5179DEAD + 5179DEAD + 5179DEAD + Danger Area + + + 5299DEAD + 5299DEAD + 5299DEAD + Danger Area + + + 5376DEAD + 5376DEAD + 5376DEAD + Danger Area + + + 6353DEAD + 6353DEAD + 6353DEAD + Danger Area + + + 6155DEAD + 6155DEAD + 6155DEAD + Danger Area + + + GATE14 + GATE14 + GATE14 + Truck Stop + + + GATE16 + GATE16 + GATE16 + Truck Stop + + + GATE17 + GATE17 + GATE17 + Truck Stop + + + GATE19 + GATE19 + GATE19 + Truck Stop + + + GATE21 + GATE21 + GATE21 + Truck Stop + + + GATE24 + GATE24 + GATE24 + Truck Stop + + + GATE5 + GATE5 + GATE5 + Truck Stop + + + GATE6 + GATE6 + GATE6 + Waypoint + + + 6077LOGS + 6077LOGS + 6077LOGS + Amusement Park + + + 5148NANEPA + 5148NANEPA + 5148NANEPA + Waypoint + + + 5267OBSTAC + 5267OBSTAC + 5267OBSTAC + Amusement Park + + + PANTHRCAVE + PANTHRCAVE + PANTHRCAVE + Tunnel + + + 5252PURPLE + 5252PURPLE + 5252PURPLE + Summit + + + 5287WATER + 5287WATER + 5287WATER + Swimming Area + + + 5239ROAD + 5239ROAD + 5239ROAD + Truck Stop + + + 5278ROAD + 5278ROAD + 5278ROAD + Truck Stop + + + 5058ROAD + 5058ROAD + 5058ROAD + Dot + + + SHEEPFOLD + SHEEPFOLD + SHEEPFOLD + Parking Area + + + SOAPBOX + SOAPBOX + SOAPBOX + Cemetery + + + 5376STREAM + 5376STREAM + 5376STREAM + Bridge + + + 5144SUMMIT + 5144SUMMIT + 5144SUMMIT + Summit + + + 5150TANK + 5150TANK + 5150TANK + Museum + + + + + 1.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2.000000 + + + + + + + 1.000000 + + + + + + + + + + + + + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + + + + 2.000000 + + + + + + + + + + + + + + + + + + + 6.000000 + + + + 2.000000 + + + + + + + + + + + + + + + + 1.000000 + + + + + + + + + + 6.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 7.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/hiketech.ref b/reference/hiketech.ref new file mode 100644 index 000000000..7082a81ff --- /dev/null +++ b/reference/hiketech.ref @@ -0,0 +1,1530 @@ + + + + + 2002-05-25 05:06:21 + 30.062183 + -91.610350 + 1.000000 + + + 2002-05-25 05:09:55 + 30.062783 + -91.610567 + + + 2002-05-25 05:12:00 + 30.062700 + -91.608267 + + + 2002-05-25 05:12:48 + 30.062333 + -91.607383 + + + 2002-05-25 05:14:41 + 30.061533 + -91.605283 + + + 2002-05-25 05:17:16 + 30.059783 + -91.599400 + + + 2002-05-25 05:17:46 + 30.057800 + -91.596683 + + + 2002-05-25 05:18:20 + 30.055383 + -91.594900 + + + 2002-05-25 05:19:01 + 30.053883 + -91.592617 + + + 2002-05-25 05:20:46 + 30.049733 + -91.589750 + + + 2002-05-25 05:21:10 + 30.049017 + -91.589883 + + + 2002-05-25 05:21:51 + 30.048800 + -91.592933 + + + 2002-05-25 05:22:35 + 30.046233 + -91.596450 + + + 2002-05-25 05:23:08 + 30.045517 + -91.598717 + + + 2002-05-25 06:04:23 + 30.047300 + -91.600267 + + + 2002-05-25 06:06:04 + 30.047000 + -91.599633 + 2.000000 + + + 2002-05-25 06:07:06 + 30.046433 + -91.599467 + + + 2002-05-25 06:08:18 + 30.046200 + -91.598950 + 1.000000 + + + 2002-05-25 06:10:20 + 30.046367 + -91.597733 + + + 2002-05-25 06:11:09 + 30.046350 + -91.597167 + + + 2002-05-25 06:12:18 + 30.046783 + -91.596333 + + + 2002-05-25 06:14:22 + 30.047450 + -91.595200 + + + 2002-05-25 06:15:04 + 30.047800 + -91.594767 + 2.000000 + + + 2002-05-25 06:16:14 + 30.048250 + -91.594083 + 1.000000 + + + 2002-05-25 06:17:01 + 30.048683 + -91.593800 + 1.000000 + + + 2002-05-25 06:18:07 + 30.049350 + -91.593850 + + + 2002-05-25 06:19:51 + 30.050317 + -91.593983 + 2.000000 + + + 2002-05-25 06:20:39 + 30.050783 + -91.594117 + + + 2002-05-25 06:21:24 + 30.051233 + -91.594367 + + + 2002-05-25 06:22:17 + 30.051800 + -91.594367 + + + 2002-05-25 06:23:18 + 30.052217 + -91.594667 + + + 2002-05-25 06:24:37 + 30.053017 + -91.594683 + + + 2002-05-25 06:28:13 + 30.054867 + -91.595200 + 6.000000 + + + 2002-05-25 06:31:36 + 30.053733 + -91.594933 + 2.000000 + + + 2002-05-25 06:32:56 + 30.053183 + -91.594783 + + + 2002-05-25 06:34:02 + 30.052633 + -91.594833 + + + 2002-05-25 06:36:03 + 30.052450 + -91.595433 + + + 2002-05-25 06:36:48 + 30.052483 + -91.595967 + + + 2002-05-25 06:37:52 + 30.052650 + -91.596783 + 1.000000 + + + 2002-05-25 06:39:18 + 30.053133 + -91.597850 + + + 2002-05-25 06:40:15 + 30.053617 + -91.597967 + + + 2002-05-25 06:41:25 + 30.053967 + -91.597767 + 6.000000 + + + 2002-05-25 06:42:37 + 30.053617 + -91.598083 + + + 2002-05-25 06:44:01 + 30.053200 + -91.597917 + + + 2002-05-25 06:45:53 + 30.052817 + -91.597517 + + + 2002-05-25 06:46:54 + 30.052567 + -91.596933 + + + 2002-05-25 06:47:42 + 30.052333 + -91.596433 + + + 2002-05-25 06:48:41 + 30.052250 + -91.595683 + + + 2002-05-25 06:49:52 + 30.052217 + -91.595017 + + + 2002-05-25 06:50:49 + 30.051883 + -91.594700 + + + 2002-05-25 06:52:14 + 30.051050 + -91.594400 + + + 2002-05-25 06:52:56 + 30.050567 + -91.594233 + + + 2002-05-25 06:53:38 + 30.050183 + -91.594100 + + + 2002-05-25 06:55:11 + 30.049100 + -91.593717 + + + 2002-05-25 06:56:32 + 30.048450 + -91.594250 + + + 2002-05-25 06:57:24 + 30.048083 + -91.594750 + + + 2002-05-25 06:58:40 + 30.047500 + -91.595450 + 7.000000 + + + 2002-05-25 06:59:28 + 30.047067 + -91.596000 + + + 2002-05-25 07:00:22 + 30.046633 + -91.596600 + + + 2002-05-25 07:01:41 + 30.046400 + -91.597650 + + + 2002-05-25 07:02:48 + 30.046233 + -91.598467 + + + 2002-05-25 07:03:43 + 30.046317 + -91.598967 + + + 2002-05-25 07:04:49 + 30.046783 + -91.599283 + + + 2002-05-25 07:05:57 + 30.047133 + -91.599667 + + + + 2002-05-25 05:06:21 + 30.062183 + -91.610350 + 1.000000 + + + 2002-05-25 05:09:55 + 30.062783 + -91.610567 + + + 2002-05-25 05:12:00 + 30.062700 + -91.608267 + + + 2002-05-25 05:12:48 + 30.062333 + -91.607383 + + + 2002-05-25 05:14:41 + 30.061533 + -91.605283 + + + 2002-05-25 05:17:16 + 30.059783 + -91.599400 + + + 2002-05-25 05:17:46 + 30.057800 + -91.596683 + + + 2002-05-25 05:18:20 + 30.055383 + -91.594900 + + + 2002-05-25 05:19:01 + 30.053883 + -91.592617 + + + 2002-05-25 05:20:46 + 30.049733 + -91.589750 + + + 2002-05-25 05:21:10 + 30.049017 + -91.589883 + + + 2002-05-25 05:21:51 + 30.048800 + -91.592933 + + + 2002-05-25 05:22:35 + 30.046233 + -91.596450 + + + 2002-05-25 05:23:08 + 30.045517 + -91.598717 + + + 2002-05-25 06:04:23 + 30.047300 + -91.600267 + + + 2002-05-25 06:06:04 + 30.047000 + -91.599633 + 2.000000 + + + 2002-05-25 06:07:06 + 30.046433 + -91.599467 + + + 2002-05-25 06:08:18 + 30.046200 + -91.598950 + 1.000000 + + + 2002-05-25 06:10:20 + 30.046367 + -91.597733 + + + 2002-05-25 06:11:09 + 30.046350 + -91.597167 + + + 2002-05-25 06:12:18 + 30.046783 + -91.596333 + + + 2002-05-25 06:14:22 + 30.047450 + -91.595200 + + + 2002-05-25 06:15:04 + 30.047800 + -91.594767 + 2.000000 + + + 2002-05-25 06:16:14 + 30.048250 + -91.594083 + 1.000000 + + + 2002-05-25 06:17:01 + 30.048683 + -91.593800 + 1.000000 + + + 2002-05-25 06:18:07 + 30.049350 + -91.593850 + + + 2002-05-25 06:19:51 + 30.050317 + -91.593983 + 2.000000 + + + 2002-05-25 06:20:39 + 30.050783 + -91.594117 + + + 2002-05-25 06:21:24 + 30.051233 + -91.594367 + + + 2002-05-25 06:22:17 + 30.051800 + -91.594367 + + + 2002-05-25 06:23:18 + 30.052217 + -91.594667 + + + 2002-05-25 06:24:37 + 30.053017 + -91.594683 + + + 2002-05-25 06:28:13 + 30.054867 + -91.595200 + 6.000000 + + + 2002-05-25 06:31:36 + 30.053733 + -91.594933 + 2.000000 + + + 2002-05-25 06:32:56 + 30.053183 + -91.594783 + + + 2002-05-25 06:34:02 + 30.052633 + -91.594833 + + + 2002-05-25 06:36:03 + 30.052450 + -91.595433 + + + 2002-05-25 06:36:48 + 30.052483 + -91.595967 + + + 2002-05-25 06:37:52 + 30.052650 + -91.596783 + 1.000000 + + + 2002-05-25 06:39:18 + 30.053133 + -91.597850 + + + 2002-05-25 06:40:15 + 30.053617 + -91.597967 + + + 2002-05-25 06:41:25 + 30.053967 + -91.597767 + 6.000000 + + + 2002-05-25 06:42:37 + 30.053617 + -91.598083 + + + 2002-05-25 06:44:01 + 30.053200 + -91.597917 + + + 2002-05-25 06:45:53 + 30.052817 + -91.597517 + + + 2002-05-25 06:46:54 + 30.052567 + -91.596933 + + + 2002-05-25 06:47:42 + 30.052333 + -91.596433 + + + 2002-05-25 06:48:41 + 30.052250 + -91.595683 + + + 2002-05-25 06:49:52 + 30.052217 + -91.595017 + + + 2002-05-25 06:50:49 + 30.051883 + -91.594700 + + + 2002-05-25 06:52:14 + 30.051050 + -91.594400 + + + 2002-05-25 06:52:56 + 30.050567 + -91.594233 + + + 2002-05-25 06:53:38 + 30.050183 + -91.594100 + + + 2002-05-25 06:55:11 + 30.049100 + -91.593717 + + + 2002-05-25 06:56:32 + 30.048450 + -91.594250 + + + 2002-05-25 06:57:24 + 30.048083 + -91.594750 + + + 2002-05-25 06:58:40 + 30.047500 + -91.595450 + 7.000000 + + + 2002-05-25 06:59:28 + 30.047067 + -91.596000 + + + 2002-05-25 07:00:22 + 30.046633 + -91.596600 + + + 2002-05-25 07:01:41 + 30.046400 + -91.597650 + + + 2002-05-25 07:02:48 + 30.046233 + -91.598467 + + + 2002-05-25 07:03:43 + 30.046317 + -91.598967 + + + 2002-05-25 07:04:49 + 30.046783 + -91.599283 + + + 2002-05-25 07:05:57 + 30.047133 + -91.599667 + + + 5066 + Crossing + 42.438878 + -71.119277 + + FAFFB4 + FF8000 + + + + 5067 + Dot + 42.439227 + -71.119689 + + FAFFB4 + FF8000 + + + + 5096 + Dot + 42.438917 + -71.116146 + + FAFFB4 + FF8000 + + + + 5142 + Dot + 42.443904 + -71.122044 + + FAFFB4 + FF8000 + + + + 5156 + Dot + 42.447298 + -71.121447 + + FAFFB4 + FF8000 + + + + 5224 + Dot + 42.454873 + -71.125094 + + FAFFB4 + FF8000 + + + + 5229 + Dot + 42.459079 + -71.124988 + + FAFFB4 + FF8000 + + + + 5237 + Dot + 42.456979 + -71.124474 + + FAFFB4 + FF8000 + + + + 5254 + Dot + 42.454401 + -71.120990 + + FAFFB4 + FF8000 + + + + 5258 + Dot + 42.451442 + -71.121746 + + FAFFB4 + FF8000 + + + + 5264 + Dot + 42.454404 + -71.120660 + + FAFFB4 + FF8000 + + + + 526708 + Dot + 42.457761 + -71.121045 + + FAFFB4 + FF8000 + + + + 526750 + Dot + 42.457089 + -71.120313 + + FAFFB4 + FF8000 + + + + 527614 + Dot + 42.456592 + -71.119676 + + FAFFB4 + FF8000 + + + + 527631 + Dot + 42.456252 + -71.119356 + + FAFFB4 + FF8000 + + + + 5278 + Dot + 42.458148 + -71.119135 + + FAFFB4 + FF8000 + + + + 5289 + Dot + 42.459377 + -71.117693 + + FAFFB4 + FF8000 + + + + 5374FIRE + Dot + 42.464183 + -71.119828 + + FAFFB4 + FF8000 + + + + 5376 + Dot + 42.465650 + -71.119399 + + FAFFB4 + FF8000 + + + + 6006 + Dot + 42.439018 + -71.114456 + + FAFFB4 + FF8000 + + + + 6006BLUE + Dot + 42.438594 + -71.114803 + + FAFFB4 + FF8000 + + + + 6014MEADOW + Dot + 42.436757 + -71.113223 + + FAFFB4 + FF8000 + + + + 6029 + Dot + 42.441754 + -71.113220 + + FAFFB4 + FF8000 + + + + 6053 + Dot + 42.436243 + -71.109075 + + FAFFB4 + FF8000 + + + + 6066 + Dot + 42.439250 + -71.107500 + + FAFFB4 + FF8000 + + + + 6067 + Dot + 42.439764 + -71.107582 + + FAFFB4 + FF8000 + + + + 6071 + Dot + 42.434766 + -71.105874 + + FAFFB4 + FF8000 + + + + 6073 + Dot + 42.433304 + -71.106599 + + FAFFB4 + FF8000 + + + + 6084 + Dot + 42.437338 + -71.104772 + + FAFFB4 + FF8000 + + + + 6130 + Dot + 42.442196 + -71.110975 + + FAFFB4 + FF8000 + + + + 6131 + Dot + 42.442981 + -71.111441 + + FAFFB4 + FF8000 + + + + 6153 + Dot + 42.444773 + -71.108882 + + FAFFB4 + FF8000 + + + + 6171 + Dot + 42.443592 + -71.106301 + + FAFFB4 + FF8000 + + + + 6176 + Dot + 42.447804 + -71.106624 + + FAFFB4 + FF8000 + + + + 6177 + Dot + 42.448448 + -71.106158 + + FAFFB4 + FF8000 + + + + 6272 + Dot + 42.453415 + -71.106783 + + FAFFB4 + FF8000 + + + + 6272 + Dot + 42.453434 + -71.107253 + + FAFFB4 + FF8000 + + + + 6278 + Dot + 42.458298 + -71.106771 + + FAFFB4 + FF8000 + + + + 6280 + Dot + 42.451430 + -71.105413 + + FAFFB4 + FF8000 + + + + 6283 + Dot + 42.453845 + -71.105206 + + FAFFB4 + FF8000 + + + + 6289 + Dot + 42.459986 + -71.106170 + + FAFFB4 + FF8000 + + + + 6297 + Dot + 42.457616 + -71.105116 + + FAFFB4 + FF8000 + + + + 6328 + Dot + 42.467110 + -71.113574 + + FAFFB4 + FF8000 + + + + 6354 + Dot + 42.464202 + -71.109863 + + FAFFB4 + FF8000 + + + + 635722 + Dot + 42.466459 + -71.110067 + + FAFFB4 + FF8000 + + + + 635783 + Dot + 42.466557 + -71.109410 + + FAFFB4 + FF8000 + + + + 6373 + Dot + 42.463495 + -71.107117 + + FAFFB4 + FF8000 + + + + 6634 + Dot + 42.401051 + -71.110241 + + FAFFB4 + FF8000 + + + + 6979 + Dot + 42.432621 + -71.106532 + + FAFFB4 + FF8000 + + + + 6997 + Dot + 42.431033 + -71.107883 + + FAFFB4 + FF8000 + + + + BEAR HILL + Tall Tower + 42.465687 + -71.107360 + + FAFFB4 + FF8000 + + + + BELLEVUE + Parking Area + 42.430950 + -71.107628 + + FAFFB4 + FF8000 + + + + 6016 + Waypoint + 42.438666 + -71.114079 + + FAFFB4 + FF8000 + + + + 5236BRIDGE + Bridge + 42.456469 + -71.124651 + + FAFFB4 + FF8000 + + + + 5376BRIDGE + Bridge + 42.465759 + -71.119815 + + FAFFB4 + FF8000 + + + + 6181CROSS + Crossing + 42.442993 + -71.105878 + + FAFFB4 + FF8000 + + + + 6042CROSS + Crossing + 42.435472 + -71.109664 + + FAFFB4 + FF8000 + + + + DARKHOLLPO + Fishing Area + 42.458516 + -71.103646 + + FAFFB4 + FF8000 + + + + 6121DEAD + Danger Area + 42.443109 + -71.112675 + + FAFFB4 + FF8000 + + + + 5179DEAD + Danger Area + 42.449866 + -71.119298 + + FAFFB4 + FF8000 + + + + 5299DEAD + Danger Area + 42.459629 + -71.116524 + + FAFFB4 + FF8000 + + + + 5376DEAD + Danger Area + 42.465485 + -71.119148 + + FAFFB4 + FF8000 + + + + 6353DEAD + Danger Area + 42.462776 + -71.109986 + + FAFFB4 + FF8000 + + + + 6155DEAD + Danger Area + 42.446793 + -71.108784 + + FAFFB4 + FF8000 + + + + GATE14 + Truck Stop + 42.451204 + -71.126602 + + FAFFB4 + FF8000 + + + + GATE16 + Truck Stop + 42.458499 + -71.122078 + + FAFFB4 + FF8000 + + + + GATE17 + Truck Stop + 42.459376 + -71.119238 + + FAFFB4 + FF8000 + + + + GATE19 + Truck Stop + 42.466353 + -71.119240 + + FAFFB4 + FF8000 + + + + GATE21 + Truck Stop + 42.468655 + -71.107697 + + FAFFB4 + FF8000 + + + + GATE24 + Truck Stop + 42.456718 + -71.102973 + + FAFFB4 + FF8000 + + + + GATE5 + Truck Stop + 42.430847 + -71.107690 + + FAFFB4 + FF8000 + + + + GATE6 + Waypoint + 42.431240 + -71.109236 + + FAFFB4 + FF8000 + + + + 6077LOGS + Amusement Park + 42.439502 + -71.106556 + + FAFFB4 + FF8000 + + + + 5148NANEPA + Waypoint + 42.449765 + -71.122320 + + FAFFB4 + FF8000 + + + + 5267OBSTAC + Amusement Park + 42.457388 + -71.119845 + + FAFFB4 + FF8000 + + + + PANTHRCAVE + Tunnel + 42.434980 + -71.109942 + + FAFFB4 + FF8000 + + + + 5252PURPLE + Summit + 42.453256 + -71.121211 + + FAFFB4 + FF8000 + + + + 5287WATER + Swimming Area + 42.457734 + -71.117481 + + FAFFB4 + FF8000 + + + + 5239ROAD + Truck Stop + 42.459278 + -71.124574 + + FAFFB4 + FF8000 + + + + 5278ROAD + Truck Stop + 42.458782 + -71.118991 + + FAFFB4 + FF8000 + + + + 5058ROAD + Dot + 42.439993 + -71.120925 + + FAFFB4 + FF8000 + + + + SHEEPFOLD + Parking Area + 42.453415 + -71.106782 + + FAFFB4 + FF8000 + + + + SOAPBOX + Cemetery + 42.455956 + -71.107483 + + FAFFB4 + FF8000 + + + + 5376STREAM + Bridge + 42.465913 + -71.119328 + + FAFFB4 + FF8000 + + + + 5144SUMMIT + Summit + 42.445359 + -71.122845 + + FAFFB4 + FF8000 + + + + 5150TANK + Museum + 42.441727 + -71.121676 + + FAFFB4 + FF8000 + + + + diff --git a/reference/igc1.gpx b/reference/igc1.gpx index 63e3ef55d..8dacba50d 100644 --- a/reference/igc1.gpx +++ b/reference/igc1.gpx @@ -1,4 +1,4 @@ - + + + 0001 IGCDATE000000: diff --git a/reference/igc2_gpx.out b/reference/igc2_gpx.out index 1a5fb96ed..df34daebf 100644 --- a/reference/igc2_gpx.out +++ b/reference/igc2_gpx.out @@ -1,4 +1,4 @@ - + + 0001 IGCDATE160701: 500KTri diff --git a/reference/kartex-out.kwf b/reference/kartex-out.kwf new file mode 100644 index 000000000..4ca65b836 --- /dev/null +++ b/reference/kartex-out.kwf @@ -0,0 +1,13 @@ +//Kartex Waypoint File created by GPSBabel +&KWF 2.0,sweref 99 lat long,0 +#,0,GC1B51,N56.078617° E13.124417°,0.00,,,0,GC1B51,$ +#,1,GC1DE6,N56.391183° E12.896183°,0.00,,,0,GC1DE6,$ +#,2,GC1E56,N57.476533° E12.173367°,0.00,,,0,GC1E56,$ +#,3,GC2182,N56.227117° E14.356100°,0.00,,,0,GC2182,$ +#,4,GC23F6,N57.363950° E12.843100°,0.00,,,0,GC23F6,$ +#,5,GC28B4,N56.330150° E14.377283°,0.00,,,0,GC28B4,$ +#,6,GC2A45,N56.713300° E13.026650°,0.00,,,0,GC2A45,$ +#,7,GC2AFD,N56.191017° E14.271100°,0.00,,,0,GC2AFD,$ +#,8,GC2BC9,N56.142467° E14.564767°,0.00,,,0,GC2BC9,$ +#,9,GC2BCA,N56.301983° E13.060750°,0.00,,,0,GC2BCA,$ +#,10,GC2D31,N57.374733° E12.916517°,0.00,,,0,GC2D31,$ diff --git a/reference/kartex.txt b/reference/kartex.txt new file mode 100644 index 000000000..e8761b380 --- /dev/null +++ b/reference/kartex.txt @@ -0,0 +1,16 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint GC1B51 User Waypoint N56 04.717 E13 07.465 0 m Symbol & Name Unknown Waypoint +Waypoint GC1DE6 User Waypoint N56 23.471 E12 53.771 0 m Symbol & Name Unknown Waypoint +Waypoint GC1E56 User Waypoint N57 28.592 E12 10.402 0 m Symbol & Name Unknown Waypoint +Waypoint GC2182 User Waypoint N56 13.627 E14 21.366 0 m Symbol & Name Unknown Waypoint +Waypoint GC23F6 User Waypoint N57 21.837 E12 50.586 0 m Symbol & Name Unknown Waypoint +Waypoint GC28B4 User Waypoint N56 19.809 E14 22.637 0 m Symbol & Name Unknown Waypoint +Waypoint GC2A45 User Waypoint N56 42.798 E13 01.599 0 m Symbol & Name Unknown Waypoint +Waypoint GC2AFD User Waypoint N56 11.461 E14 16.266 0 m Symbol & Name Unknown Waypoint +Waypoint GC2BC9 User Waypoint N56 08.548 E14 33.886 0 m Symbol & Name Unknown Waypoint +Waypoint GC2BCA User Waypoint N56 18.119 E13 03.645 0 m Symbol & Name Unknown Waypoint +Waypoint GC2D31 User Waypoint N57 22.484 E12 54.991 0 m Symbol & Name Unknown Waypoint diff --git a/reference/mxf.mxf b/reference/mxf.mxf index ea6d6088e..98d93d1a0 100644 --- a/reference/mxf.mxf +++ b/reference/mxf.mxf @@ -1,9 +1,9 @@ -35.97203, -87.13470, Mountain Bike Heaven by susy1313, GCEBB, Mountain Bike Heaven by susy1313, ff0000, 47 -36.09068, -86.67955, The Troll by a182pilot & Family, GC1A37, The Troll by a182pilot & Family, ff0000, 47 -35.99627, -86.62012, Dive Bomber by JoGPS & family, GC1C2B, Dive Bomber by JoGPS & family, ff0000, 47 -36.03848, -86.64862, FOSTER by JoGPS & Family, GC25A9, FOSTER by JoGPS & Family, ff0000, 47 -36.11218, -86.74177, Logan Lighthouse by JoGps & Family, GC2723, Logan Lighthouse by JoGps & Family, ff0000, 47 -36.06408, -86.79052, Ganier Cache by Susy1313, GC2B71, Ganier Cache by Susy1313, ff0000, 47 -36.08777, -86.80973, Shy's Hill by FireFighterEng33, GC309F, Shy's Hill by FireFighterEng33, ff0000, 47 -36.05750, -86.89200, GittyUp by JoGPS / Warner Parks, GC317A, GittyUp by JoGPS / Warner Parks, ff0000, 47 -36.08280, -86.86728, Inlighting by JoGPS / Warner Parks, GC317D, Inlighting by JoGPS / Warner Parks, ff0000, 47 +35.97203, -87.13470, "Mountain Bike Heaven by susy1313", "GCEBB", "Mountain Bike Heaven by susy1313", ff0000, 47 +36.09068, -86.67955, "The Troll by a182pilot & Family", "GC1A37", "The Troll by a182pilot & Family", ff0000, 47 +35.99627, -86.62012, "Dive Bomber by JoGPS & family", "GC1C2B", "Dive Bomber by JoGPS & family", ff0000, 47 +36.03848, -86.64862, "FOSTER by JoGPS & Family", "GC25A9", "FOSTER by JoGPS & Family", ff0000, 47 +36.11218, -86.74177, "Logan Lighthouse by JoGps & Family", "GC2723", "Logan Lighthouse by JoGps & Family", ff0000, 47 +36.06408, -86.79052, "Ganier Cache by Susy1313", "GC2B71", "Ganier Cache by Susy1313", ff0000, 47 +36.08777, -86.80973, "Shy's Hill by FireFighterEng33", "GC309F", "Shy's Hill by FireFighterEng33", ff0000, 47 +36.05750, -86.89200, "GittyUp by JoGPS / Warner Parks", "GC317A", "GittyUp by JoGPS / Warner Parks", ff0000, 47 +36.08280, -86.86728, "Inlighting by JoGPS / Warner Parks", "GC317D", "Inlighting by JoGPS / Warner Parks", ff0000, 47 diff --git a/reference/ov2-in.ref b/reference/ov2-in.ref index 4c0e75dee..8ce96c6f2 100644 --- a/reference/ov2-in.ref +++ b/reference/ov2-in.ref @@ -1,9 +1,9 @@ -Mountain Bike Heaven by susy1313 3558.322N 08708.081W 0000000m Mountain Bike Heaven by susy13 a -The Troll by a182pilot & Family 3605.441N 08640.772W 0000000m The Troll by a182pilot & Famil a -Dive Bomber by JoGPS & family 3559.776N 08637.207W 0000000m Dive Bomber by JoGPS & family a -FOSTER by JoGPS & Family 3602.309N 08638.917W 0000000m FOSTER by JoGPS & Family a -Logan Lighthouse by JoGps & Family 3606.731N 08644.506W 0000000m Logan Lighthouse by JoGps & Fa a -Ganier Cache by Susy1313 3603.845N 08647.431W 0000000m Ganier Cache by Susy1313 a -Shy's Hill by FireFighterEng33 3605.266N 08648.583W 0000000m Shy's Hill by FireFighterEng33 a -GittyUp by JoGPS / Warner Parks 3603.450N 08653.519W 0000000m GittyUp by JoGPS / Warner Park a -Inlighting by JoGPS / Warner Parks 3604.968N 08652.036W 0000000m Inlighting by JoGPS / Warner P a +Mountain 3558.322N 08708.081W 0000000m Mountain Bike Heaven by susy13 a +The Trol 3605.441N 08640.772W 0000000m The Troll by a182pilot & Famil a +Dive Bom 3559.776N 08637.207W 0000000m Dive Bomber by JoGPS & family a +FOSTER b 3602.309N 08638.917W 0000000m FOSTER by JoGPS & Family a +Logan Li 3606.731N 08644.506W 0000000m Logan Lighthouse by JoGps & Fa a +Ganier C 3603.845N 08647.431W 0000000m Ganier Cache by Susy1313 a +Shy's Hi 3605.266N 08648.583W 0000000m Shy's Hill by FireFighterEng33 a +GittyUp 3603.450N 08653.519W 0000000m GittyUp by JoGPS / Warner Park a +Inlighti 3604.968N 08652.036W 0000000m Inlighting by JoGPS / Warner P a diff --git a/reference/route/bcr-sample.gpx b/reference/route/bcr-sample.gpx index eb4d8b21e..7f1983fa9 100644 --- a/reference/route/bcr-sample.gpx +++ b/reference/route/bcr-sample.gpx @@ -1,4 +1,4 @@ - + + + + + + test + + 0.000000 + V03087 + Waypoint + + + 0.000000 + V05027 + Waypoint + + + 0.000000 + V06080 + Waypoint + + + 0.000000 + V04041 + Waypoint + + + 0.000000 + V09058 + Waypoint + + + 0.000000 + V10025 + Waypoint + + + 0.000000 + V02023 + Waypoint + + + diff --git a/reference/route/compegps.rte b/reference/route/compegps.rte new file mode 100644 index 000000000..f07304ede --- /dev/null +++ b/reference/route/compegps.rte @@ -0,0 +1,20 @@ +G WGS 84 + U 1 + R 16711680 , test , 1 , -1 + W V03087__________ A 45.7893830000ºN 11.5535830000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V05027__________ A 45.7758000000ºN 11.4499670000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V06080__________ A 45.7848830000ºN 11.5444170000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V04041__________ A 45.7544670000ºN 11.4939500000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V09058__________ A 45.7830830000ºN 11.4590830000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V10025__________ A 45.7605830000ºN 11.4496170000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + W V02023__________ A 45.7659500000ºN 11.4806170000ºE 27-MAR-62 00:00:00 0.000000 + w Waypoint , 0 , -1.0 , 16777215 , 255 , 1 , 7 , , 0.0 + + + \ No newline at end of file diff --git a/reference/route/cst-sample.cst b/reference/route/cst-sample.cst new file mode 100644 index 000000000..4db803380 --- /dev/null +++ b/reference/route/cst-sample.cst @@ -0,0 +1,351 @@ +#CARTE SUR TABLE DATA FILE +; Saved 21/06/2005 00:08:38 +; USER : lilou COMPUTER : MAISON1 +; NAME : +; CarteSurTable version 4.0.0.7 +; date format : yyyy mm dd hh:nn:ss + +#VERSION +40 + +#NOTES +Très belle rando, mais trop tôt dans la saison. Le pic du midi était inaccessible car le parcours était complètement enneigé. La descente par le GR de pays, face sud est superbe. + +#REFERENCE +GRID 0 (UTM/UPS) +LEN 1000.0 3 (Mètres) +ORIGIN 10.000 246.220 266295 4757286 +X-AXIS 246.220 246.220 +Y-AXIS 10.000 10.000 +FEET 0 +ZONE 31 0 +DATUM 100 (WGS 84) +METHOD 0 +EQU DEGREE: 1 + +#ROUTE +; x y z interp [start] [NAME:name] [ ^ date] [ ¤ symb] +303 Points +271440 4756533 1266.2 0 1 ^ 2005 06 18 08:45:06 +271447 4756542 1268.1 0 ^ 2005 06 18 08:51:06 +271446 4756552 1267.6 0 ^ 2005 06 18 08:51:21 +271442 4756550 1268.1 0 ^ 2005 06 18 08:51:25 +271444 4756540 1268.6 0 ^ 2005 06 18 08:51:40 +271442 4756538 1270 0 ^ 2005 06 18 08:52:01 +271421 4756534 1271.5 0 ^ 2005 06 18 08:52:17 +271394 4756527 1274.4 0 ^ 2005 06 18 08:52:33 +271371 4756521 1273.4 0 ^ 2005 06 18 08:52:57 +271369 4756521 1272.9 0 NAME:1 ^ 2005 06 18 08:53:36 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0446.JPG +;¤note +Vue de notre chemin du retour.., mais c'est par la route qu'on monte +;¤end +271368 4756521 1272.9 0 ^ 2005 06 18 08:53:42 +271365 4756512 1273.9 0 ^ 2005 06 18 08:53:46 +271316 4756459 1280.1 0 ^ 2005 06 18 08:54:13 +271262 4756420 1286.4 0 ^ 2005 06 18 08:54:37 +271253 4756411 1286.9 0 ^ 2005 06 18 08:54:42 +271258 4756391 1288.8 0 ^ 2005 06 18 08:54:49 +271294 4756318 1290.7 0 ^ 2005 06 18 08:55:21 +271341 4756191 1291.2 0 ^ 2005 06 18 08:56:19 +271432 4756247 1291.2 0 ^ 2005 06 18 08:56:35 +271489 4756174 1291.2 0 ^ 2005 06 18 08:56:59 +271500 4756169 1291.2 0 ^ 2005 06 18 08:57:04 +271527 4756201 1307 0 ^ 2005 06 18 08:57:15 +271532 4756191 1307 0 ^ 2005 06 18 08:57:17 +271540 4756184 1307.5 0 ^ 2005 06 18 08:57:21 +271582 4756175 1308.5 0 ^ 2005 06 18 08:57:42 +271656 4756187 1311.4 0 ^ 2005 06 18 08:58:30 +271682 4756172 1312.3 0 ^ 2005 06 18 08:58:51 +271769 4756160 1317.6 0 ^ 2005 06 18 08:59:38 +271859 4756104 1320 0 ^ 2005 06 18 09:00:37 +271865 4756097 1326.3 0 ^ 2005 06 18 09:02:27 +271901 4756057 1326.3 0 ^ 2005 06 18 09:02:51 +271957 4756001 1334.9 0 ^ 2005 06 18 09:03:28 +271984 4755933 1343.1 0 ^ 2005 06 18 09:04:01 +272032 4755848 1350.3 0 ^ 2005 06 18 09:04:47 +272056 4755771 1356.6 0 ^ 2005 06 18 09:05:25 +272120 4755637 1362.3 0 ^ 2005 06 18 09:06:34 +272166 4755543 1368.1 0 ^ 2005 06 18 09:07:24 +272154 4755498 1371.5 0 ^ 2005 06 18 09:07:48 +272193 4755446 1372.9 0 ^ 2005 06 18 09:08:19 +272234 4755385 1382.5 0 ^ 2005 06 18 09:08:54 +272220 4755379 1388.3 0 ^ 2005 06 18 09:09:03 +272203 4755384 1391.6 0 ^ 2005 06 18 09:09:12 +272163 4755438 1403.2 0 ^ 2005 06 18 09:09:45 +272111 4755518 1414.2 0 ^ 2005 06 18 09:10:30 +272064 4755587 1424.3 0 ^ 2005 06 18 09:11:10 +272013 4755648 1434.4 0 ^ 2005 06 18 09:11:50 +271937 4755713 1437.3 0 ^ 2005 06 18 09:12:37 +271912 4755754 1440.2 0 ^ 2005 06 18 09:13:01 +271844 4755837 1447.9 0 ^ 2005 06 18 09:13:51 +271777 4755909 1450.3 0 ^ 2005 06 18 09:14:37 +271741 4755929 1456.5 0 ^ 2005 06 18 09:14:59 +271668 4755955 1459.4 0 ^ 2005 06 18 09:15:36 +271577 4756006 1465.2 0 ^ 2005 06 18 09:16:28 +271512 4756013 1521.9 0 ^ 2005 06 18 09:17:00 +271434 4755982 1521.4 0 ^ 2005 06 18 09:17:42 +271352 4755942 1524.3 0 ^ 2005 06 18 09:18:30 +271355 4755940 1525.3 0 NAME:2 ^ 2005 06 18 09:18:44 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0448.JPG +;¤note +Notre objectif. +;¤end +271355 4755942 1525.3 0 ^ 2005 06 18 09:19:08 +271385 4755953 1524.3 0 ^ 2005 06 18 09:19:16 +271384 4755955 1524.8 0 ^ 2005 06 18 09:19:20 +271378 4755951 1526.2 0 ^ 2005 06 18 09:19:39 +271348 4755930 1530.1 0 ^ 2005 06 18 09:20:01 +271350 4755930 1530.6 0 ^ 2005 06 18 09:20:17 +271333 4755914 1533 0 ^ 2005 06 18 09:22:06 +271271 4755878 1536.8 0 ^ 2005 06 18 09:22:39 +271190 4755833 1539.2 0 ^ 2005 06 18 09:23:21 +271101 4755779 1561.8 0 ^ 2005 06 18 09:26:01 +271058 4755756 1565.2 0 ^ 2005 06 18 09:26:27 +271021 4755743 1568 0 ^ 2005 06 18 09:26:46 +270977 4755735 1571.9 0 ^ 2005 06 18 09:27:06 +270973 4755733 1572.9 0 ^ 2005 06 18 09:27:22 +270966 4755733 1572.4 0 ^ 2005 06 18 09:28:54 +270954 4755726 1572.4 0 ^ 2005 06 18 09:29:00 +270878 4755726 1579.6 0 ^ 2005 06 18 09:29:35 +270813 4755714 1584.9 0 ^ 2005 06 18 09:30:08 +270736 4755674 1591.6 0 ^ 2005 06 18 09:30:53 +270712 4755641 1595.9 0 ^ 2005 06 18 09:31:14 +270666 4755578 1602.2 0 ^ 2005 06 18 09:31:55 +270614 4755525 1609.4 0 ^ 2005 06 18 09:32:35 +270561 4755467 1616.1 0 ^ 2005 06 18 09:33:16 +270513 4755402 1623.3 0 ^ 2005 06 18 09:34:00 +270499 4755396 1626.2 0 ^ 2005 06 18 09:34:08 +270478 4755360 1630.5 0 ^ 2005 06 18 09:34:30 +270439 4755343 1636.3 0 ^ 2005 06 18 09:34:55 +270401 4755287 1643 0 ^ 2005 06 18 09:35:34 +270400 4755225 1648.8 0 ^ 2005 06 18 09:36:09 +270376 4755187 1652.6 0 ^ 2005 06 18 09:36:36 +270353 4755133 1656 0 ^ 2005 06 18 09:37:10 +270353 4755121 1657.5 0 ^ 2005 06 18 09:37:18 +270313 4755042 1672.4 0 ^ 2005 06 18 09:38:24 +270297 4755035 1678.1 0 ^ 2005 06 18 09:38:33 +270253 4755017 1683.4 0 ^ 2005 06 18 09:39:01 +270180 4754972 1689.7 0 ^ 2005 06 18 09:39:49 +270152 4754925 1694.9 0 ^ 2005 06 18 09:40:20 +270132 4754857 1700.2 0 ^ 2005 06 18 09:41:02 +270083 4754811 1707 0 ^ 2005 06 18 09:41:46 +270021 4754784 1713.7 0 ^ 2005 06 18 09:42:25 +270001 4754768 1716.1 0 ^ 2005 06 18 09:42:41 +269999 4754773 1715.6 0 ^ 2005 06 18 09:42:45 +270003 4754768 1716.1 0 ^ 2005 06 18 09:42:54 +270003 4754773 1716.1 0 ^ 2005 06 18 09:42:57 +270008 4754780 1716.1 0 ^ 2005 06 18 09:43:11 +270008 4754777 1716.6 0 ^ 2005 06 18 09:43:17 +270003 4754778 1717.1 0 ^ 2005 06 18 09:43:22 +269972 4754750 1721.4 0 ^ 2005 06 18 09:43:46 +269929 4754723 1725.2 0 ^ 2005 06 18 09:44:18 +269874 4754706 1728.6 0 ^ 2005 06 18 09:44:53 +269846 4754702 1730.5 0 ^ 2005 06 18 09:45:12 +269835 4754690 1730 0 ^ 2005 06 18 09:45:38 +269837 4754690 1732.9 0 ^ 2005 06 18 09:46:32 +269833 4754690 1733.4 0 ^ 2005 06 18 09:46:51 +269821 4754691 1734.8 0 ^ 2005 06 18 09:46:57 +269816 4754691 1735.8 0 ^ 2005 06 18 09:47:01 +269811 4754693 1736.3 0 ^ 2005 06 18 09:47:04 +269779 4754694 1740.1 0 ^ 2005 06 18 09:47:22 +269738 4754712 1743 0 ^ 2005 06 18 09:47:48 +269724 4754763 1744 0 ^ 2005 06 18 09:48:14 +269706 4754802 1744.9 0 ^ 2005 06 18 09:48:37 +269654 4754818 1747.3 0 ^ 2005 06 18 09:49:09 +269601 4754817 1747.3 0 ^ 2005 06 18 09:49:39 +269571 4754814 1747.3 0 ^ 2005 06 18 09:49:56 +269555 4754750 1818 0 ^ 2005 06 18 09:50:15 +269518 4754746 1802.1 0 ^ 2005 06 18 09:50:35 +269472 4754736 1802.1 0 ^ 2005 06 18 09:51:03 +269397 4754741 1803.6 0 ^ 2005 06 18 09:51:45 +269339 4754738 1804.5 0 ^ 2005 06 18 09:52:19 +269280 4754725 1806 0 ^ 2005 06 18 09:52:53 +269215 4754718 1808.9 0 ^ 2005 06 18 09:53:31 +269140 4754725 1811.7 0 ^ 2005 06 18 09:54:15 +269065 4754730 1815.6 0 ^ 2005 06 18 09:55:02 +269035 4754734 1817.5 0 ^ 2005 06 18 09:55:19 +268955 4754736 1822.3 0 ^ 2005 06 18 09:56:06 +268903 4754714 1826.6 0 ^ 2005 06 18 09:56:40 +268834 4754688 1832.4 0 ^ 2005 06 18 09:57:23 +268773 4754657 1837.2 0 ^ 2005 06 18 09:58:03 +268696 4754654 1843 0 ^ 2005 06 18 09:58:47 +268668 4754655 1845.9 0 ^ 2005 06 18 09:59:03 +268597 4754677 1851.2 0 ^ 2005 06 18 09:59:46 +268543 4754686 1856 0 ^ 2005 06 18 10:00:17 +268541 4754686 1856 0 ^ 2005 06 18 10:00:18 +268536 4754689 1856.9 0 ^ 2005 06 18 10:00:22 +268506 4754687 1859.3 0 ^ 2005 06 18 10:00:42 +268490 4754681 1860.8 0 ^ 2005 06 18 10:00:55 +268483 4754676 1861.7 0 ^ 2005 06 18 10:01:02 +268440 4754673 1865.1 0 ^ 2005 06 18 10:01:30 +268378 4754646 1870.4 0 ^ 2005 06 18 10:02:12 +268337 4754626 1874.7 0 ^ 2005 06 18 10:02:42 +268284 4754606 1879.5 0 ^ 2005 06 18 10:03:17 +268273 4754604 1880.5 0 ^ 2005 06 18 10:03:24 +268271 4754602 1881 0 ^ 2005 06 18 10:03:27 +268263 4754600 1881.9 0 ^ 2005 06 18 10:03:33 +268208 4754585 1886.7 0 ^ 2005 06 18 10:04:11 +268150 4754575 1892 0 ^ 2005 06 18 10:04:49 +268110 4754557 1896.3 0 ^ 2005 06 18 10:05:14 +268069 4754525 1899.7 0 ^ 2005 06 18 10:05:46 +268033 4754491 1903.1 0 ^ 2005 06 18 10:06:18 +268018 4754484 1905.5 0 ^ 2005 06 18 10:06:30 +268008 4754482 1906.4 0 ^ 2005 06 18 10:06:36 +267947 4754441 1911.2 0 ^ 2005 06 18 10:07:21 +267904 4754407 1915.6 0 ^ 2005 06 18 10:07:54 +267879 4754396 1919.4 0 ^ 2005 06 18 10:08:12 +267845 4754385 1922.8 0 ^ 2005 06 18 10:08:33 +267774 4754368 1928.5 0 ^ 2005 06 18 10:09:16 +267713 4754366 1933.8 0 ^ 2005 06 18 10:09:53 +267664 4754372 1937.2 0 ^ 2005 06 18 10:10:23 +267668 4754379 1939.6 0 ^ 2005 06 18 10:10:30 +267676 4754381 1942 0 ^ 2005 06 18 10:10:44 +267677 4754386 1941.5 0 ^ 2005 06 18 10:11:39 +267680 4754386 1940.6 0 ^ 2005 06 18 10:21:10 +267682 4754391 1941 0 ^ 2005 06 18 10:21:14 +267684 4754390 1942 0 ^ 2005 06 18 10:21:29 +267684 4754388 1942.5 0 ^ 2005 06 18 10:21:54 +267724 4754384 1945.4 0 ^ 2005 06 18 10:22:15 +267758 4754409 1948.7 0 ^ 2005 06 18 10:22:40 +267805 4754458 1954.5 0 ^ 2005 06 18 10:23:22 +267821 4754493 1958.3 0 ^ 2005 06 18 10:23:47 +267859 4754528 1962.7 0 ^ 2005 06 18 10:24:18 +267856 4754561 1966.5 0 ^ 2005 06 18 10:24:38 +267871 4754596 1970.4 0 ^ 2005 06 18 10:25:03 +267866 4754654 1975.6 0 ^ 2005 06 18 10:25:39 +267851 4754714 1980.9 0 ^ 2005 06 18 10:26:19 +267871 4754747 1984.3 0 ^ 2005 06 18 10:26:42 +267849 4754767 1988.1 0 ^ 2005 06 18 10:27:01 +267815 4754749 1991 0 ^ 2005 06 18 10:27:23 +267782 4754702 1995.4 0 ^ 2005 06 18 10:27:58 +267750 4754675 1999.2 0 ^ 2005 06 18 10:28:23 +267728 4754654 2002.1 0 ^ 2005 06 18 10:28:42 +267726 4754647 2002.6 0 ^ 2005 06 18 10:28:46 +267709 4754604 2006.9 0 ^ 2005 06 18 10:29:14 +267655 4754580 2012.7 0 ^ 2005 06 18 10:29:49 +267611 4754584 2016 0 ^ 2005 06 18 10:30:17 +267548 4754622 2020.8 0 ^ 2005 06 18 10:30:59 +267511 4754632 2024.7 0 ^ 2005 06 18 10:31:22 +267456 4754653 2029.5 0 ^ 2005 06 18 10:32:00 +267408 4754643 2033.3 0 ^ 2005 06 18 10:32:30 +267353 4754614 2037.7 0 ^ 2005 06 18 10:33:06 +267295 4754616 2042.5 0 ^ 2005 06 18 10:33:42 +267261 4754608 2046.3 0 ^ 2005 06 18 10:34:06 +267257 4754541 2050.1 0 ^ 2005 06 18 10:34:39 +267242 4754494 2055.4 0 ^ 2005 06 18 10:35:09 +267232 4754456 2059.8 0 ^ 2005 06 18 10:35:35 +267196 4754385 2066.5 0 ^ 2005 06 18 10:36:25 +267204 4754347 2069.9 0 ^ 2005 06 18 10:36:48 +267207 4754337 2070.8 0 ^ 2005 06 18 10:36:54 +267197 4754323 2073.7 0 ^ 2005 06 18 10:37:07 +267187 4754326 2075.6 0 ^ 2005 06 18 10:37:14 +267174 4754358 2079.5 0 ^ 2005 06 18 10:37:32 +267161 4754430 2086.7 0 ^ 2005 06 18 10:38:15 +267149 4754485 2092.4 0 ^ 2005 06 18 10:38:48 +267145 4754487 2093.9 0 ^ 2005 06 18 10:38:52 +267127 4754512 2096.8 0 ^ 2005 06 18 10:39:12 +267112 4754534 2099.7 0 ^ 2005 06 18 10:39:30 +267076 4754571 2104.5 0 ^ 2005 06 18 10:40:05 +267076 4754573 2104.5 0 ^ 2005 06 18 10:40:06 +267070 4754583 2106.4 0 ^ 2005 06 18 10:40:15 +267041 4754613 2111.2 0 ^ 2005 06 18 10:40:43 +267036 4754618 2111.7 0 ^ 2005 06 18 10:40:48 +267013 4754628 2114.1 0 ^ 2005 06 18 10:41:06 +267010 4754626 2114.6 0 ^ 2005 06 18 10:41:09 +266999 4754626 2116 0 ^ 2005 06 18 10:41:17 +266961 4754601 2118.4 0 ^ 2005 06 18 10:41:44 +266960 4754599 2118.4 0 ^ 2005 06 18 10:41:47 +266952 4754594 2118.4 0 ^ 2005 06 18 10:41:52 +266933 4754590 2118.9 0 ^ 2005 06 18 10:42:06 +266931 4754593 2119.4 0 ^ 2005 06 18 10:42:25 +266928 4754595 2119.8 0 ^ 2005 06 18 10:42:29 +266919 4754598 2120.8 0 NAME:3 ^ 2005 06 18 10:42:43 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0449.JPG +;¤note +Au col, fini la route, bonjour les touristes! +;¤end +266921 4754595 2119.8 0 ^ 2005 06 18 10:45:07 +266919 4754598 2120.8 0 ^ 2005 06 18 10:45:24 +266919 4754600 2120.8 0 ^ 2005 06 18 10:45:26 +266916 4754605 2121.3 0 ^ 2005 06 18 10:45:32 +266914 4754610 2121.8 0 ^ 2005 06 18 10:45:53 +266916 4754610 2121.3 0 ^ 2005 06 18 10:46:24 +266919 4754602 2120.8 0 ^ 2005 06 18 10:46:43 +266918 4754600 2120.8 0 ^ 2005 06 18 10:47:29 +266919 4754600 2120.8 0 ^ 2005 06 18 10:47:58 +266923 4754607 2120.8 0 ^ 2005 06 18 10:48:27 +266923 4754609 2120.8 0 ^ 2005 06 18 10:48:40 +266921 4754610 2120.8 0 ^ 2005 06 18 10:48:43 +266914 4754607 2121.3 0 ^ 2005 06 18 10:49:01 +266907 4754610 2121.8 0 ^ 2005 06 18 10:49:07 +266861 4754626 2124.7 0 ^ 2005 06 18 10:49:34 +266824 4754644 2127.5 0 ^ 2005 06 18 10:49:57 +266819 4754646 2128 0 ^ 2005 06 18 10:50:00 +266805 4754649 2129.5 0 ^ 2005 06 18 10:50:09 +266737 4754664 2134.3 0 ^ 2005 06 18 10:50:49 +266708 4754688 2137.1 0 ^ 2005 06 18 10:51:13 +266692 4754715 2139.1 0 ^ 2005 06 18 10:51:30 +266686 4754742 2142 0 ^ 2005 06 18 10:51:49 +266708 4754772 2145.8 0 ^ 2005 06 18 10:52:12 +266721 4754812 2150.1 0 ^ 2005 06 18 10:52:37 +266734 4754864 2153.5 0 ^ 2005 06 18 10:53:06 +266734 4754917 2157.8 0 ^ 2005 06 18 10:53:38 +266732 4754928 2159.3 0 ^ 2005 06 18 10:53:55 +266731 4754936 2160.2 0 ^ 2005 06 18 10:54:27 +266732 4754967 2163.6 0 ^ 2005 06 18 10:54:44 +266742 4754995 2166.5 0 ^ 2005 06 18 10:55:02 +266740 4755002 2166.9 0 ^ 2005 06 18 10:55:07 +266711 4755029 2167.9 0 ^ 2005 06 18 10:55:30 +266704 4755085 2170.3 0 ^ 2005 06 18 10:56:00 +266713 4755127 2174.6 0 ^ 2005 06 18 10:56:27 +266728 4755151 2177.5 0 ^ 2005 06 18 10:56:54 +266726 4755153 2178 0 ^ 2005 06 18 10:57:22 +266753 4755183 2181.4 0 ^ 2005 06 18 10:57:42 +266802 4755222 2185.7 0 ^ 2005 06 18 10:58:16 +266824 4755257 2188.6 0 ^ 2005 06 18 10:58:46 +266822 4755257 2187.1 0 NAME:4 ^ 2005 06 18 10:59:13 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0458.JPG +;¤note +La piste semble bien enneigée... +;¤end +266822 4755255 2188.1 0 ^ 2005 06 18 10:59:51 +266855 4755289 2192.9 0 ^ 2005 06 18 11:01:09 +266881 4755329 2196.3 0 ^ 2005 06 18 11:01:31 +266899 4755386 2200.6 0 ^ 2005 06 18 11:02:02 +266889 4755427 2204.9 0 ^ 2005 06 18 11:02:24 +266829 4755462 2208.8 0 ^ 2005 06 18 11:03:02 +266824 4755465 2209.2 0 ^ 2005 06 18 11:03:06 +266823 4755472 2210.2 0 ^ 2005 06 18 11:03:13 +266819 4755474 2211.7 0 ^ 2005 06 18 11:03:27 +266806 4755487 2212.1 0 ^ 2005 06 18 11:03:48 +266800 4755492 2212.1 0 ^ 2005 06 18 11:04:00 +266765 4755517 2216.9 0 ^ 2005 06 18 11:04:25 +266732 4755544 2220.3 0 ^ 2005 06 18 11:04:51 +266701 4755571 2223.7 0 ^ 2005 06 18 11:05:17 +266661 4755566 2226.1 0 ^ 2005 06 18 11:05:39 +266604 4755539 2230.4 0 ^ 2005 06 18 11:06:14 +266577 4755530 2232.3 0 NAME:5 ^ 2005 06 18 11:06:30 +;¤bitmap C:\Mesdoc\Mes images\pic midi\DSCF0459.JPG +;¤note +Entrée du premier tunnel. Bien plein! +;¤end +266570 4755530 2232.8 0 ^ 2005 06 18 11:06:34 +266546 4755546 2237.1 0 ^ 2005 06 18 11:06:57 +266547 4755553 2237.6 0 ^ 2005 06 18 11:07:19 +266539 4755577 2239 0 1 ^ 2005 06 18 11:08:05 +266531 4755570 2244.3 0 ^ 2005 06 18 11:08:16 +266530 4755584 2244.8 0 ^ 2005 06 18 11:08:34 +266532 4755587 2244.8 0 ^ 2005 06 18 11:08:41 +266557 4755612 2247.7 0 ^ 2005 06 18 11:09:03 +266575 4755664 2249.1 0 ^ 2005 06 18 11:09:28 +266584 4755683 2249.6 0 ^ 2005 06 18 11:09:36 +266585 4755747 2251.5 0 ^ 2005 06 18 11:10:06 +266583 4755845 2253.5 0 ^ 2005 06 18 11:10:56 +266582 4755874 2254.9 0 ^ 2005 06 18 11:11:12 +266566 4755908 2258.3 0 ^ 2005 06 18 11:11:34 +266562 4755955 2260.7 0 ^ 2005 06 18 11:12:02 +266541 4756001 2263.6 0 ^ 2005 06 18 11:12:31 +266518 4756050 2266.4 0 ^ 2005 06 18 11:13:04 +266495 4756096 2270.8 0 ^ 2005 06 18 11:13:38 +266475 4756168 2274.6 0 ^ 2005 06 18 11:14:25 diff --git a/reference/route/cst-sample.cst.gz b/reference/route/cst-sample.cst.gz new file mode 100644 index 0000000000000000000000000000000000000000..c6c02b8d88ff2ffe8cef68da2246d71c92883536 GIT binary patch literal 4470 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 IPv$xR053)(Jpcdz literal 0 HcmV?d00001 diff --git a/reference/route/cst-sample.gpx b/reference/route/cst-sample.gpx new file mode 100644 index 000000000..82ca4ce63 --- /dev/null +++ b/reference/route/cst-sample.gpx @@ -0,0 +1,1312 @@ + + + + + + 1272.900000 + + 1 + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0446.JPG + + + 1525.300000 + + 2 + Notre objectif. + Notre objectif. + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0448.JPG + + + 2120.800000 + + 3 + Au col, fini la route, bonjour les touristes! + Au col, fini la route, bonjour les touristes! + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0449.JPG + + + 2187.100000 + + 4 + La piste semble bien enneigée... + La piste semble bien enneigée... + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0458.JPG + + + 2232.300000 + + 5 + Entrée du premier tunnel. Bien plein! + Entrée du premier tunnel. Bien plein! + file://C:/Mesdoc/Mes%20images/pic%20midi/DSCF0459.JPG + + + + 1272.900000 + + 1 + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + + + 1525.300000 + + 2 + Notre objectif. + + + 2120.800000 + + 3 + Au col, fini la route, bonjour les touristes! + + + 2187.100000 + + 4 + La piste semble bien enneigée... + + + 2232.300000 + + 5 + Entrée du premier tunnel. Bien plein! + + + + + + 1266.200000 + + + + 1268.100000 + + + + 1267.600000 + + + + 1268.100000 + + + + 1268.600000 + + + + 1270.000000 + + + + 1271.500000 + + + + 1274.400000 + + + + 1273.400000 + + + + 1272.900000 + + 1 + Vue de notre chemin du retour.., mais c'est par la route qu'on monte + + + 1272.900000 + + + + 1273.900000 + + + + 1280.100000 + + + + 1286.400000 + + + + 1286.900000 + + + + 1288.800000 + + + + 1290.700000 + + + + 1291.200000 + + + + 1291.200000 + + + + 1291.200000 + + + + 1291.200000 + + + + 1307.000000 + + + + 1307.000000 + + + + 1307.500000 + + + + 1308.500000 + + + + 1311.400000 + + + + 1312.300000 + + + + 1317.600000 + + + + 1320.000000 + + + + 1326.300000 + + + + 1326.300000 + + + + 1334.900000 + + + + 1343.100000 + + + + 1350.300000 + + + + 1356.600000 + + + + 1362.300000 + + + + 1368.100000 + + + + 1371.500000 + + + + 1372.900000 + + + + 1382.500000 + + + + 1388.300000 + + + + 1391.600000 + + + + 1403.200000 + + + + 1414.200000 + + + + 1424.300000 + + + + 1434.400000 + + + + 1437.300000 + + + + 1440.200000 + + + + 1447.900000 + + + + 1450.300000 + + + + 1456.500000 + + + + 1459.400000 + + + + 1465.200000 + + + + 1521.900000 + + + + 1521.400000 + + + + 1524.300000 + + + + 1525.300000 + + 2 + Notre objectif. + + + 1525.300000 + + + + 1524.300000 + + + + 1524.800000 + + + + 1526.200000 + + + + 1530.100000 + + + + 1530.600000 + + + + 1533.000000 + + + + 1536.800000 + + + + 1539.200000 + + + + 1561.800000 + + + + 1565.200000 + + + + 1568.000000 + + + + 1571.900000 + + + + 1572.900000 + + + + 1572.400000 + + + + 1572.400000 + + + + 1579.600000 + + + + 1584.900000 + + + + 1591.600000 + + + + 1595.900000 + + + + 1602.200000 + + + + 1609.400000 + + + + 1616.100000 + + + + 1623.300000 + + + + 1626.200000 + + + + 1630.500000 + + + + 1636.300000 + + + + 1643.000000 + + + + 1648.800000 + + + + 1652.600000 + + + + 1656.000000 + + + + 1657.500000 + + + + 1672.400000 + + + + 1678.100000 + + + + 1683.400000 + + + + 1689.700000 + + + + 1694.900000 + + + + 1700.200000 + + + + 1707.000000 + + + + 1713.700000 + + + + 1716.100000 + + + + 1715.600000 + + + + 1716.100000 + + + + 1716.100000 + + + + 1716.100000 + + + + 1716.600000 + + + + 1717.100000 + + + + 1721.400000 + + + + 1725.200000 + + + + 1728.600000 + + + + 1730.500000 + + + + 1730.000000 + + + + 1732.900000 + + + + 1733.400000 + + + + 1734.800000 + + + + 1735.800000 + + + + 1736.300000 + + + + 1740.100000 + + + + 1743.000000 + + + + 1744.000000 + + + + 1744.900000 + + + + 1747.300000 + + + + 1747.300000 + + + + 1747.300000 + + + + 1818.000000 + + + + 1802.100000 + + + + 1802.100000 + + + + 1803.600000 + + + + 1804.500000 + + + + 1806.000000 + + + + 1808.900000 + + + + 1811.700000 + + + + 1815.600000 + + + + 1817.500000 + + + + 1822.300000 + + + + 1826.600000 + + + + 1832.400000 + + + + 1837.200000 + + + + 1843.000000 + + + + 1845.900000 + + + + 1851.200000 + + + + 1856.000000 + + + + 1856.000000 + + + + 1856.900000 + + + + 1859.300000 + + + + 1860.800000 + + + + 1861.700000 + + + + 1865.100000 + + + + 1870.400000 + + + + 1874.700000 + + + + 1879.500000 + + + + 1880.500000 + + + + 1881.000000 + + + + 1881.900000 + + + + 1886.700000 + + + + 1892.000000 + + + + 1896.300000 + + + + 1899.700000 + + + + 1903.100000 + + + + 1905.500000 + + + + 1906.400000 + + + + 1911.200000 + + + + 1915.600000 + + + + 1919.400000 + + + + 1922.800000 + + + + 1928.500000 + + + + 1933.800000 + + + + 1937.200000 + + + + 1939.600000 + + + + 1942.000000 + + + + 1941.500000 + + + + 1940.600000 + + + + 1941.000000 + + + + 1942.000000 + + + + 1942.500000 + + + + 1945.400000 + + + + 1948.700000 + + + + 1954.500000 + + + + 1958.300000 + + + + 1962.700000 + + + + 1966.500000 + + + + 1970.400000 + + + + 1975.600000 + + + + 1980.900000 + + + + 1984.300000 + + + + 1988.100000 + + + + 1991.000000 + + + + 1995.400000 + + + + 1999.200000 + + + + 2002.100000 + + + + 2002.600000 + + + + 2006.900000 + + + + 2012.700000 + + + + 2016.000000 + + + + 2020.800000 + + + + 2024.700000 + + + + 2029.500000 + + + + 2033.300000 + + + + 2037.700000 + + + + 2042.500000 + + + + 2046.300000 + + + + 2050.100000 + + + + 2055.400000 + + + + 2059.800000 + + + + 2066.500000 + + + + 2069.900000 + + + + 2070.800000 + + + + 2073.700000 + + + + 2075.600000 + + + + 2079.500000 + + + + 2086.700000 + + + + 2092.400000 + + + + 2093.900000 + + + + 2096.800000 + + + + 2099.700000 + + + + 2104.500000 + + + + 2104.500000 + + + + 2106.400000 + + + + 2111.200000 + + + + 2111.700000 + + + + 2114.100000 + + + + 2114.600000 + + + + 2116.000000 + + + + 2118.400000 + + + + 2118.400000 + + + + 2118.400000 + + + + 2118.900000 + + + + 2119.400000 + + + + 2119.800000 + + + + 2120.800000 + + 3 + Au col, fini la route, bonjour les touristes! + + + 2119.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2121.300000 + + + + 2121.800000 + + + + 2121.300000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2120.800000 + + + + 2121.300000 + + + + 2121.800000 + + + + 2124.700000 + + + + 2127.500000 + + + + 2128.000000 + + + + 2129.500000 + + + + 2134.300000 + + + + 2137.100000 + + + + 2139.100000 + + + + 2142.000000 + + + + 2145.800000 + + + + 2150.100000 + + + + 2153.500000 + + + + 2157.800000 + + + + 2159.300000 + + + + 2160.200000 + + + + 2163.600000 + + + + 2166.500000 + + + + 2166.900000 + + + + 2167.900000 + + + + 2170.300000 + + + + 2174.600000 + + + + 2177.500000 + + + + 2178.000000 + + + + 2181.400000 + + + + 2185.700000 + + + + 2188.600000 + + + + 2187.100000 + + 4 + La piste semble bien enneigée... + + + 2188.100000 + + + + 2192.900000 + + + + 2196.300000 + + + + 2200.600000 + + + + 2204.900000 + + + + 2208.800000 + + + + 2209.200000 + + + + 2210.200000 + + + + 2211.700000 + + + + 2212.100000 + + + + 2212.100000 + + + + 2216.900000 + + + + 2220.300000 + + + + 2223.700000 + + + + 2226.100000 + + + + 2230.400000 + + + + 2232.300000 + + 5 + Entrée du premier tunnel. Bien plein! + + + 2232.800000 + + + + 2237.100000 + + + + 2237.600000 + + + + + + + + 2239.000000 + + + + 2244.300000 + + + + 2244.800000 + + + + 2244.800000 + + + + 2247.700000 + + + + 2249.100000 + + + + 2249.600000 + + + + 2251.500000 + + + + 2253.500000 + + + + 2254.900000 + + + + 2258.300000 + + + + 2260.700000 + + + + 2263.600000 + + + + 2266.400000 + + + + 2270.800000 + + + + 2274.600000 + + + + + diff --git a/reference/route/mag_pdb-sample.gpx b/reference/route/mag_pdb-sample.gpx new file mode 100644 index 000000000..8a23e61db --- /dev/null +++ b/reference/route/mag_pdb-sample.gpx @@ -0,0 +1,1034 @@ + + + + + + Jägersburg in Forchheim geradeaus weiter auf Eisenbahnstrasse + Jägersburg in Forchheim geradeaus weiter auf Eisenbahnstrasse + Eisenbahnstrasse + + + Rettern in Jägersburg halb rechts halten auf Fürstenweg (FO17) + Rettern in Jägersburg halb rechts halten auf Fürstenweg (FO17) + Fürstenweg (FO17) + + + Kauernhofen bei D 91330 Eggolsheim/Rettern + Kauernhofen bei D 91330 Eggolsheim/Rettern + FO11\Kanzelstrasse + + + Eggolsheim bei D 91330 Eggolsheim/Kauernhofen + Eggolsheim bei D 91330 Eggolsheim/Kauernhofen + FO11\Andreas-Knauer-Strasse + + + Weigelshofen in Eggolsheim rechts abbiegen auf FO5 + Weigelshofen in Eggolsheim rechts abbiegen auf FO5 + FO5 + + + Drosendorf a. Eggerbach rechts abbiegen auf Bachgasse + Drosendorf a. Eggerbach rechts abbiegen auf Bachgasse + Bachgasse + + + Ebermannstadt bei D 91320 Ebermannstadt/Feuerstein + Ebermannstadt bei D 91320 Ebermannstadt/Feuerstein + FO41 + + + Gasseldorf bei D91320 Ebermannstadt + Gasseldorf bei D91320 Ebermannstadt + ST2260\Breitenbacher Strasse + + + Streitberg bei D91320 Ebermannstadt/Gasseldorf + Streitberg bei D91320 Ebermannstadt/Gasseldorf + B470 + + + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + + + Traindorf bei D 91364 Unterleinleiter + Traindorf bei D 91364 Unterleinleiter + ST2187 + + + Neumühle bei D 91332 Heiligenstadt + Neumühle bei D 91332 Heiligenstadt + ST2187\Hauptstrasse + + + Hohenpölz in Neumühle links abbiegen auf Neumühle + Hohenpölz in Neumühle links abbiegen auf Neumühle + Neumühle + + + Voitmannsdorf bei D 91332 Heiligenstadt/Hohenpölz + Voitmannsdorf bei D 91332 Heiligenstadt/Hohenpölz + BA11\Hohenpölz + + + Hollfeld bei D 96142 Hollfeld/Drosendorf a d Aufseß + Hollfeld bei D 96142 Hollfeld/Drosendorf a d Aufseß + ST2281\Drosendorf an der Aufsess + + + Stechendorf bei D96142 Hollfeld + Stechendorf bei D96142 Hollfeld + ST2191\Bahnhofstrasse + + + Nankendorf D 95515 Plankenfels + Nankendorf D 95515 Plankenfels + ST2191\Hauptstrasse + + + Waischenfeld halb links halten auf Gutenbiegen (ST2191) + Waischenfeld halb links halten auf Gutenbiegen (ST2191) + Gutenbiegen (ST2191) + + + Behringersmühle bei D 91327 Gößweinstein/Schweigelberg + Behringersmühle bei D 91327 Gößweinstein/Schweigelberg + ST2191 + + + Tüchersfeld links abbiegen auf B470 + Tüchersfeld links abbiegen auf B470 + B470 + + + Pottenstein bei D 91278 Pottenstein/Tüchersfeld + Pottenstein bei D 91278 Pottenstein/Tüchersfeld + B470 + + + Wannberg bei D 91278 Pottenstein + Wannberg bei D 91278 Pottenstein + B470\Pegnitzer Strasse + + + Bronn bei D91257 Pegnitz/Lüglas + Bronn bei D91257 Pegnitz/Lüglas + B470 + + + Kühlenfels in Bronn rechts abbiegen auf BT33 Kühlenfelser Strasse + Kühlenfels in Bronn rechts abbiegen auf BT33 Kühlenfelser Strasse + BT33 Kühlenfelser Strasse + + + Kirchenbirkig bei D 91278 Pottenstein/Kleinkirchenbirkig + Kirchenbirkig bei D 91278 Pottenstein/Kleinkirchenbirkig + BT33\Langhausenweg + + + Siegmannsbrunn in Kirchenbirkig rechts abbiegen auf Sankt-Johannes-Strasse (ST2163) + Siegmannsbrunn in Kirchenbirkig rechts abbiegen auf Sankt-Johannes-Strasse (ST2163) + Sankt-Johannes-Strasse (ST2163) + + + Gössweinstein bei D 91327 Gößweinstein/Hühnerloh + Gössweinstein bei D 91327 Gößweinstein/Hühnerloh + ST2685 + + + Kleingesee halb rechts halten auf ST2191 + Kleingesee halb rechts halten auf ST2191 + ST2191 + + + Bieberbach D 91327 Gößweinstein/Kleingesee + Bieberbach D 91327 Gößweinstein/Kleingesee + ST2191\Kleingesee + + + Wichsenstein bei D 91327 Gößweinstein/Wichsenstein + Wichsenstein bei D 91327 Gößweinstein/Wichsenstein + FO21 + + + Hardt in Wichsenstein links abbiegen auf Wichsenstein (FO37) + Hardt in Wichsenstein links abbiegen auf Wichsenstein (FO37) + Wichsenstein (FO37) + + + Wannbach in Sattelmannsburg halb links halten auf Sattelmannsburg (FO37) + Wannbach in Sattelmannsburg halb links halten auf Sattelmannsburg (FO37) + Sattelmannsburg (FO37) + + + Unterzaunsbach in Wannbach links abbiegen auf Wannbach (ST2260) + Unterzaunsbach in Wannbach links abbiegen auf Wannbach (ST2260) + Wannbach (ST2260) + + + Schweinthal bei D 91362 Pretzfeld/Unterzaunsbach + Schweinthal bei D 91362 Pretzfeld/Unterzaunsbach + ST2260\Unterzaunsbach + + + Egloffstein bei D 91349 Egloffstein + Egloffstein bei D 91349 Egloffstein + ST2260 + + + Thuisbrunn in Egloffstein rechts abbiegen auf Felsenkellerstrasse (ST2242) + Thuisbrunn in Egloffstein rechts abbiegen auf Felsenkellerstrasse (ST2242) + Felsenkellerstrasse (ST2242) + + + Hohenschwärz bei D 91322 Gräfenberg/Thuisbrunn + Hohenschwärz bei D 91322 Gräfenberg/Thuisbrunn + FO32 + + + Gräfenberg in Hohenschwärz halb links halten auf Hohenschwärz (FO32) + Gräfenberg in Hohenschwärz halb links halten auf Hohenschwärz (FO32) + Hohenschwärz (FO32) + + + Guttenberg bei D 91322 Gräfenberg/Guttenburg + Guttenberg bei D 91322 Gräfenberg/Guttenburg + FO28\Guttenburger Strasse + + + Walkersbrunn in Guttenberg rechts abbiegen auf Guttenberg (FO28) + Walkersbrunn in Guttenberg rechts abbiegen auf Guttenberg (FO28) + Guttenberg (FO28) + + + Weingarts bei D 91322 Gräfenberg/Schlichenreuth + Weingarts bei D 91322 Gräfenberg/Schlichenreuth + ST2236 + + + Kunreuth in Weingarts rechts abbiegen auf Weingarts (ST2236) + Kunreuth in Weingarts rechts abbiegen auf Weingarts (ST2236) + Weingarts (ST2236) + + + Gaiganz in Kunreuth links abbiegen auf Schlossstrasse (ST2242) + Gaiganz in Kunreuth links abbiegen auf Schlossstrasse (ST2242) + Schlossstrasse (ST2242) + + + Effeltrich bei D 91090 Effeltrich/Gaiganz + Effeltrich bei D 91090 Effeltrich/Gaiganz + ST2242\Gaiganzer Hauptstrasse + + + Honings bei D 91090 Effeltrich + Honings bei D 91090 Effeltrich + ST2242\Hauptstrasse + + + Dormitz bei D 91077 Neunkirchen + Dormitz bei D 91077 Neunkirchen + Friedhofstrasse + + + Neunhof bei D 90562 Kalchreuth + Neunhof bei D 90562 Kalchreuth + ST2243 + + + Kraftshof bei D 90427 Nürnberg/Neunhof + Kraftshof bei D 90427 Nürnberg/Neunhof + Obere Dorfstrasse + + + Buch in Kraftshof links abbiegen auf Kraftshofer Hauptstrasse + Buch in Kraftshof links abbiegen auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + D 90403 Nürnberg/Sebald in Nürnberg links abbiegen auf B4R + D 90403 Nürnberg/Sebald in Nürnberg links abbiegen auf B4R + B4R + + + + + + RPT001 + bei D91301 Forchheim Jägersburg + Klosterstrasse + + + RPT002 + Jägersburg in Forchheim geradeaus weiter auf Eisenbahnstrasse + Eisenbahnstrasse + + + RPT003 + - links abbiegen auf B470 Theodor-Heuss-Allee + B470 Theodor-Heuss-Allee + + + RPT004 + - rechts abbiegen auf Untere Kellerstrasse (FO17) + Untere Kellerstrasse (FO17) + + + RPT005 + - halb links halten auf FO17 + FO17 + + + RPT006 + Rettern in Jägersburg halb rechts halten auf Fürstenweg (FO17) + Fürstenweg (FO17) + + + RPT007 + - halb links halten auf FO11 + FO11 + + + RPT008 + Kauernhofen bei D 91330 Eggolsheim/Rettern + FO11\Kanzelstrasse + + + RPT009 + bei D 91330 Eggolsheim/Kauernhofen in Kauernhofen links abbiegen auf Andreas-Knauer-Strasse (FO11) + Andreas-Knauer-Strasse (FO11) + + + RPT010 + Eggolsheim bei D 91330 Eggolsheim/Kauernhofen + FO11\Andreas-Knauer-Strasse + + + RPT011 + - halb rechts halten auf FO11 + FO11 + + + RPT012 + Weigelshofen in Eggolsheim rechts abbiegen auf FO5 + FO5 + + + RPT013 + Drosendorf a. Eggerbach rechts abbiegen auf Bachgasse + Bachgasse + + + RPT014 + bei D91330 Eggolsheim/Drosendorf in Drosendorf a. Eggerbach rechts abbiegen auf Feuersteinstrasse (FO41) + Feuersteinstrasse (FO41) + + + RPT015 + bei D 91320 Ebermannstadt/Feuerstein bei D91330 Eggolsheim/Drosendorf + FO41\Feuersteinstrasse + + + RPT016 + Ebermannstadt bei D 91320 Ebermannstadt/Feuerstein + FO41 + + + RPT017 + bei D91320 Ebermannstadt in Ebermannstadt links abbiegen auf Altweiherstrasse + Altweiherstrasse + + + RPT018 + - links abbiegen auf Altweiherstrasse + Altweiherstrasse + + + RPT019 + - rechts abbiegen auf Eschlipper Talstrasse (ST2260) + Eschlipper Talstrasse (ST2260) + + + RPT020 + Gasseldorf bei D91320 Ebermannstadt + ST2260\Breitenbacher Strasse + + + RPT021 + - links abbiegen auf B470 Breitenbacher Strasse + B470 Breitenbacher Strasse + + + RPT022 + Streitberg bei D91320 Ebermannstadt/Gasseldorf + B470 + + + RPT023 + bei D 91346 Wiesenttal/Streitberg in Streitberg links abbiegen auf Bahnhofstrasse (ST2186) + Bahnhofstrasse (ST2186) + + + RPT024 + bei D 91346 Wiesenttal/Störnhof bei D 91346 Wiesenttal/Streitberg + ST2186\Dorfplatz + + + RPT025 + - links abbiegen auf Hadergasse + Hadergasse + + + RPT026 + - geradeaus weiter auf Schauertal + Schauertal + + + RPT027 + - geradeaus auffahren + - geradeaus auffahren + + + RPT028 + - links abbiegen + - links abbiegen + + + RPT029 + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + Unterleinleiter bei D 91346 Wiesenttal/Störnhof + + + RPT030 + bei D 91364 Unterleinleiter in Unterleinleiter rechts abbiegen auf Störnhofer Weg + Störnhofer Weg + + + RPT031 + - halb rechts halten auf Bahnhofstrasse + Bahnhofstrasse + + + RPT032 + - geradeaus weiter auf An der Leinleiter + An der Leinleiter + + + RPT033 + - rechts abbiegen auf ST2187 + ST2187 + + + RPT034 + Traindorf bei D 91364 Unterleinleiter + ST2187 + + + RPT035 + Neumühle bei D 91332 Heiligenstadt + ST2187\Hauptstrasse + + + RPT036 + - in Heiligenstadt in Oberfranken links abbiegen auf Hauptstrasse (ST2187) + Hauptstrasse (ST2187) + + + RPT037 + - rechts abbiegen auf ST2188 + ST2188 + + + RPT038 + Hohenpölz in Neumühle links abbiegen auf Neumühle + Neumühle + + + RPT039 + - geradeaus weiter auf BA11 + BA11 + + + RPT040 + - rechts abbiegen auf BA11 + BA11 + + + RPT041 + - rechts abbiegen auf BA11 + BA11 + + + RPT042 + - links abbiegen auf BA11 + BA11 + + + RPT043 + Voitmannsdorf bei D 91332 Heiligenstadt/Hohenpölz + BA11\Hohenpölz + + + RPT044 + - rechts abbiegen auf ST2281 + ST2281 + + + RPT045 + bei D 96142 Hollfeld/Drosendorf a d Aufseß in Drosendorf an der Aufsess halb links halten auf Drosendorf an der Aufsess (ST2281) + Drosendorf an der Aufsess (ST2281) + + + RPT046 + Hollfeld bei D 96142 Hollfeld/Drosendorf a d Aufseß + ST2281\Drosendorf an der Aufsess + + + RPT047 + - links halten auf Drosendorf an der Aufsess + Drosendorf an der Aufsess + + + RPT048 + - geradeaus weiter auf ST2281 + ST2281 + + + RPT049 + - links abbiegen auf ST2281 + ST2281 + + + RPT050 + bei D96142 Hollfeld in Hollfeld links abbiegen auf Forchheimer Strasse (ST2189) + Forchheimer Strasse (ST2189) + + + RPT051 + - rechts abbiegen auf Bahnhofstrasse (ST2191) + Bahnhofstrasse (ST2191) + + + RPT052 + Stechendorf bei D96142 Hollfeld + ST2191\Bahnhofstrasse + + + RPT053 + Nankendorf D 95515 Plankenfels + ST2191\Hauptstrasse + + + RPT054 + - rechts abbiegen auf Eichenmühle (ST2186/ST2191) + Eichenmühle (ST2186/ST2191) + + + RPT055 + - links abbiegen auf ST2191 + ST2191 + + + RPT056 + Waischenfeld halb links halten auf Gutenbiegen (ST2191) + Gutenbiegen (ST2191) + + + RPT057 + - links halten auf Gutenbiegen + Gutenbiegen + + + RPT058 + - halb rechts halten auf ST2191 + ST2191 + + + RPT059 + bei D 91327 Gößweinstein/Schweigelberg bei D 91344 Waischenfeld/Hammermühle + ST2191 + + + RPT060 + Behringersmühle bei D 91327 Gößweinstein/Schweigelberg + ST2191 + + + RPT061 + Tüchersfeld links abbiegen auf B470 + B470 + + + RPT062 + Pottenstein bei D 91278 Pottenstein/Tüchersfeld + B470 + + + RPT063 + - links abbiegen auf B470 + B470 + + + RPT064 + - halb links halten auf B470 + B470 + + + RPT065 + Wannberg bei D 91278 Pottenstein + B470\Pegnitzer Strasse + + + RPT066 + Bronn bei D91257 Pegnitz/Lüglas + B470 + + + RPT067 + - rechts abbiegen auf B2 + B2 + + + RPT068 + Kühlenfels in Bronn rechts abbiegen auf BT33 Kühlenfelser Strasse + BT33 Kühlenfelser Strasse + + + RPT069 + - halb links halten auf BT33 Kühlenfelser Strasse + BT33 Kühlenfelser Strasse + + + RPT070 + bei D 91278 Pottenstein/Kleinkirchenbirkig in Kühlenfels links abbiegen auf BT33 Kühlenfels + BT33 Kühlenfels + + + RPT071 + - halb links halten auf BT33 Langhausenweg + BT33 Langhausenweg + + + RPT072 + - halb rechts halten auf BT33 Langhausenweg + BT33 Langhausenweg + + + RPT073 + Kirchenbirkig bei D 91278 Pottenstein/Kleinkirchenbirkig + BT33\Langhausenweg + + + RPT074 + Siegmannsbrunn in Kirchenbirkig rechts abbiegen auf Sankt-Johannes-Strasse (ST2163) + Sankt-Johannes-Strasse (ST2163) + + + RPT075 + - halb links halten auf Sankt-Johannes-Strasse (ST2163) + Sankt-Johannes-Strasse (ST2163) + + + RPT076 + - links abbiegen auf ST2685 + ST2685 + + + RPT077 + bei D 91327 Gößweinstein/Hühnerloh halb links halten auf ST2685 + ST2685 + + + RPT078 + Gössweinstein bei D 91327 Gößweinstein/Hühnerloh + ST2685 + + + RPT079 + - links abbiegen auf ST2191 + ST2191 + + + RPT080 + Kleingesee halb rechts halten auf ST2191 + ST2191 + + + RPT081 + Bieberbach D 91327 Gößweinstein/Kleingesee + ST2191\Kleingesee + + + RPT082 + - in Kleingesee rechts abbiegen auf Kleingesee (ST2191) + Kleingesee (ST2191) + + + RPT083 + - halb rechts halten auf Kleingesee (FO43) + Kleingesee (FO43) + + + RPT084 + bei D 91327 Gößweinstein/Wichsenstein in Bieberbach rechts abbiegen auf Bieberbach (FO21) + Bieberbach (FO21) + + + RPT085 + Wichsenstein bei D 91327 Gößweinstein/Wichsenstein + FO21 + + + RPT086 + Hardt in Wichsenstein links abbiegen auf Wichsenstein (FO37) + Wichsenstein (FO37) + + + RPT087 + - rechts abbiegen auf FO37 + FO37 + + + RPT088 + Wannbach in Sattelmannsburg halb links halten auf Sattelmannsburg (FO37) + Sattelmannsburg (FO37) + + + RPT089 + - links abbiegen auf FO37 + FO37 + + + RPT090 + Unterzaunsbach in Wannbach links abbiegen auf Wannbach (ST2260) + Wannbach (ST2260) + + + RPT091 + Schweinthal bei D 91362 Pretzfeld/Unterzaunsbach + ST2260\Unterzaunsbach + + + RPT092 + Egloffstein bei D 91349 Egloffstein + ST2260 + + + RPT093 + Thuisbrunn in Egloffstein rechts abbiegen auf Felsenkellerstrasse (ST2242) + Felsenkellerstrasse (ST2242) + + + RPT094 + - geradeaus weiter auf FO32 + FO32 + + + RPT095 + bei D 91322 Gräfenberg/Thuisbrunn in Thuisbrunn links abbiegen auf Thuisbrunn (FO32) + Thuisbrunn (FO32) + + + RPT096 + Hohenschwärz bei D 91322 Gräfenberg/Thuisbrunn + FO32 + + + RPT097 + Gräfenberg in Hohenschwärz halb links halten auf Hohenschwärz (FO32) + Hohenschwärz (FO32) + + + RPT098 + - rechts abbiegen auf ST2191 + ST2191 + + + RPT099 + - rechts abbiegen auf FO14 + FO14 + + + RPT100 + bei D 91322 Gräfenberg/Guttenburg in Gräfenberg halb links halten auf Egloffsteiner Strasse (FO14) + Egloffsteiner Strasse (FO14) + + + RPT101 + - halb rechts halten auf Egloffsteiner Strasse (FO14) + Egloffsteiner Strasse (FO14) + + + RPT102 + - rechts abbiegen auf Kasberger Strasse (FO14) + Kasberger Strasse (FO14) + + + RPT103 + - links abbiegen auf Am Bach (FO28) + Am Bach (FO28) + + + RPT104 + - halb rechts halten auf Guttenburger Strasse (FO28) + Guttenburger Strasse (FO28) + + + RPT105 + Guttenberg bei D 91322 Gräfenberg/Guttenburg + FO28\Guttenburger Strasse + + + RPT106 + Walkersbrunn in Guttenberg rechts abbiegen auf Guttenberg (FO28) + Guttenberg (FO28) + + + RPT107 + - halb links halten auf Guttenberg (FO28) + Guttenberg (FO28) + + + RPT108 + - halb links halten auf Guttenberg (FO28) + Guttenberg (FO28) + + + RPT109 + bei D 91322 Gräfenberg/Walkersbrunn in Walkersbrunn rechts abbiegen auf Walkersbrunn (ST2236) + Walkersbrunn (ST2236) + + + RPT110 + bei D 91322 Gräfenberg/Schlichenreuth bei D 91322 Gräfenberg/Walkersbrunn + ST2236\Walkersbrunn + + + RPT111 + - links abbiegen auf Walkersbrunn (ST2236) + Walkersbrunn (ST2236) + + + RPT112 + - links abbiegen auf Walkersbrunn (ST2236) + Walkersbrunn (ST2236) + + + RPT113 + Weingarts bei D 91322 Gräfenberg/Schlichenreuth + ST2236 + + + RPT114 + Kunreuth in Weingarts rechts abbiegen auf Weingarts (ST2236) + Weingarts (ST2236) + + + RPT115 + Gaiganz in Kunreuth links abbiegen auf Schlossstrasse (ST2242) + Schlossstrasse (ST2242) + + + RPT116 + - geradeaus weiter auf Badanger + Badanger + + + RPT117 + - geradeaus weiter auf ST2242 + ST2242 + + + RPT118 + - links abbiegen auf ST2242 + ST2242 + + + RPT119 + bei D 91090 Effeltrich/Gaiganz in Gaiganz halb rechts halten auf Gaiganzer Hauptstrasse (ST2242) + Gaiganzer Hauptstrasse (ST2242) + + + RPT120 + Effeltrich bei D 91090 Effeltrich/Gaiganz + ST2242\Gaiganzer Hauptstrasse + + + RPT121 + - halb links halten auf ST2242 + ST2242 + + + RPT122 + bei D 91090 Effeltrich in Effeltrich rechts abbiegen auf Gaiganzer Strasse (ST2242) + Gaiganzer Strasse (ST2242) + + + RPT123 + Honings bei D 91090 Effeltrich + ST2242\Hauptstrasse + + + RPT124 + - links abbiegen auf Neunkirchener Strasse (ST2242/ST2243) + Neunkirchener Strasse (ST2242/ST2243) + + + RPT125 + - links abbiegen auf Neunkirchener Strasse (ST2243) + Neunkirchener Strasse (ST2243) + + + RPT126 + bei D 91077 Neunkirchen in Neunkirchen am Brand rechts abbiegen auf Friedhofstrasse + Friedhofstrasse + + + RPT127 + Dormitz bei D 91077 Neunkirchen + Friedhofstrasse + + + RPT128 + - geradeaus weiter auf Erleinhofer Strasse + Erleinhofer Strasse + + + RPT129 + - links abbiegen auf Henkerstegstrasse + Henkerstegstrasse + + + RPT130 + - geradeaus weiter auf Erlanger Strasse (ST2243) + Erlanger Strasse (ST2243) + + + RPT131 + - halb rechts halten auf Erlanger Strasse (ST2243) + Erlanger Strasse (ST2243) + + + RPT132 + - geradeaus weiter auf ST2240 + ST2240 + + + RPT133 + bei D 91080 Uttenreuth/Habernhofermühle links abbiegen auf ST2243 + ST2243 + + + RPT134 + bei D 90562 Kalchreuth bei D 91080 Uttenreuth/Habernhofermühle + ST2243 + + + RPT135 + Neunhof bei D 90562 Kalchreuth + ST2243 + + + RPT136 + - in Kalchreuth einfahren in Kreisverkehr + - in Kalchreuth einfahren in Kreisverkehr + + + RPT137 + - 1. Möglichkeit aus Kreisverkehr ausfahren auf Fürther Strasse (ERH6) + Fürther Strasse (ERH6) + + + RPT138 + - geradeaus weiter auf N3 Obere Dorfstrasse + N3 Obere Dorfstrasse + + + RPT139 + Kraftshof bei D 90427 Nürnberg/Neunhof + Obere Dorfstrasse + + + RPT140 + - geradeaus weiter auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + RPT141 + Buch in Kraftshof links abbiegen auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + RPT142 + - halb rechts halten auf Am Kressenstein + Am Kressenstein + + + RPT143 + - geradeaus weiter auf Kraftshofer Hauptstrasse + Kraftshofer Hauptstrasse + + + RPT144 + - links abbiegen auf B4 Erlanger Strasse + B4 Erlanger Strasse + + + RPT145 + D 90403 Nürnberg/Sebald in Nürnberg links abbiegen auf B4R + B4R + + + RPT146 + - halb rechts halten auf B4R Hintermayrstrasse + B4R Hintermayrstrasse + + + RPT147 + - rechts abbiegen auf Äussere Sulzbacher Strasse + Äussere Sulzbacher Strasse + + + RPT148 + - rechts halten auf Sulzbacher Strasse + Sulzbacher Strasse + + + RPT149 + - links abbiegen auf Bauvereinstrasse + Bauvereinstrasse + + + RPT150 + - geradeaus weiter auf Wöhrder Talübergang + Wöhrder Talübergang + + + RPT151 + - geradeaus weiter auf Dürrenhofstrasse + Dürrenhofstrasse + + + RPT152 + - links abbiegen auf Stephanstrasse + Stephanstrasse + + + RPT153 + - links abbiegen auf Hintere Cramergasse + Hintere Cramergasse + + + RPT154 + - rechts abbiegen auf Burgerstrasse + Burgerstrasse + + + diff --git a/reference/route/mag_pdb-sample.pdb b/reference/route/mag_pdb-sample.pdb new file mode 100644 index 0000000000000000000000000000000000000000..f1664e064dcf44e8bbd5791a867dc3c9e0115d74 GIT binary patch literal 16183 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 literal 0 HcmV?d00001 diff --git a/reference/route/magexplorist.rte b/reference/route/magexplorist.rte new file mode 100644 index 000000000..0ca044eda --- /dev/null +++ b/reference/route/magexplorist.rte @@ -0,0 +1,6 @@ +$PMGNWPL,3408.881,N,11750.002,W,0000356,M,WPT006,,a*2D +$PMGNWPL,3403.376,N,11742.897,W,0000273,M,WPT007,,a*25 +$PMGNWPL,3401.816,N,11751.349,W,0000226,M,WPT008,,a*2F +$PMGNWPL,3405.686,N,11751.836,W,0000201,M,WPT009,,a*2B +$PMGNRTE,2,1,c,1,Route 1,WPT006,a,WPT007,a*63 +$PMGNRTE,2,2,c,1,Route 1,WPT008,a,WPT009,a*60 diff --git a/reference/route/msroute-sample.axe b/reference/route/msroute-sample.axe new file mode 100644 index 0000000000000000000000000000000000000000..299f8e15ed06ba665470ab4a67e9ba35eaaa7b08 GIT binary patch literal 9216 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 literal 0 HcmV?d00001 diff --git a/reference/route/msroute-sample.gpx b/reference/route/msroute-sample.gpx new file mode 100644 index 000000000..ccffa0d73 --- /dev/null +++ b/reference/route/msroute-sample.gpx @@ -0,0 +1,90 @@ + + + + + + + Plauen + + + Treuen + + + Rodewisch + + + Stützengrün + + + Hundshübel + + + Zschorlau + + + Aue + + + Lauter + + + Schwarzenberg + + + Markersbach + + + Schlettau + + + Talstraße, 09456 Annaberg-Buchholz + + + Frohnau + + + Geyer + + + Zwönitz + + + Grünhain + + + Beierfeld + + + S274 + + + Sosa + + + Blauenthal + + + Schönheide + + + Schnarrtanne + + + K7820 + + + Rodewisch + + + Treuen + + + A72, 08233 Treuen + + + diff --git a/reference/route/nmn4-sample-out.rte b/reference/route/nmn4-sample-out.rte new file mode 100644 index 000000000..4f00f9ea1 --- /dev/null +++ b/reference/route/nmn4-sample-out.rte @@ -0,0 +1,10 @@ +-|-|-|-|-|-|-|-|-|-|-|12.10727|50.49425|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.01210|50.37575|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.07199|50.22467|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.67563|49.22528|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.55165|49.12409|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.26244|49.05546|-|-| +-|-|-|-|-|-|-|-|-|-|-|12.22659|49.03302|-|-| +-|-|-|-|-|-|-|-|-|-|-|11.76592|49.04841|-|-| +-|-|-|-|-|-|-|-|-|-|-|11.61610|49.02190|-|-| +-|-|-|-|-|-|-|-|-|-|-|11.58767|49.03485|-|-| diff --git a/reference/route/nmn4-sample.gpx b/reference/route/nmn4-sample.gpx new file mode 100644 index 000000000..0473d9546 --- /dev/null +++ b/reference/route/nmn4-sample.gpx @@ -0,0 +1,62 @@ + + + + + + + RPT001 + 08523 Plauen, Jahnstrasse 28 + 08523 Plauen, Jahnstrasse 28 + + + RPT002 + 08538 Burgstein, K7855 + 08538 Burgstein, K7855 + + + RPT003 + 95111 Rehau + 95111 Rehau + + + RPT004 + 93413 Cham, Further Strasse + 93413 Cham, Further Strasse + + + RPT005 + 93185 Michelsneukirchen, Hauptstrasse + 93185 Michelsneukirchen, Hauptstrasse + + + RPT006 + 93177 Altenthann + 93177 Altenthann + + + RPT007 + 93093 Donaustauf + 93093 Donaustauf + + + RPT008 + 93155 Hemau, Dietfurter Strasse + 93155 Hemau, Dietfurter Strasse + + + RPT009 + 92345 Mühlbach, Riedenburger Strasse + 92345 Mühlbach, Riedenburger Strasse + + + RPT010 + 92345 Dietfurt An Der Altmühl + 92345 Dietfurt An Der Altmühl + + + diff --git a/reference/route/nmn4-sample.rte b/reference/route/nmn4-sample.rte new file mode 100644 index 000000000..2a27a231d --- /dev/null +++ b/reference/route/nmn4-sample.rte @@ -0,0 +1,10 @@ +-|-|17|-|08523|Plauen|08523|Jahnstrasse|28|-|-|12.10727|50.49425|-|-| +-|-|17|-|08538|Burgstein|08538|K7855|-|-|-|12.01210|50.37575|-|-| +-|-|17|-|95111|Rehau|-|-|-|-|-|12.07199|50.22467|-|-| +-|-|17|-|93413|Cham|93413|Further Strasse|-|-|-|12.67563|49.22528|-|-| +-|-|17|-|93185|Michelsneukirchen|93185|Hauptstrasse|-|-|-|12.55165|49.12409|-|-| +-|-|17|-|93177|Altenthann|-|-|-|-|-|12.26244|49.05546|-|-| +-|-|17|-|93093|Donaustauf|-|-|-|-|-|12.22659|49.03302|-|-| +-|-|17|-|93155|Hemau|93155|Dietfurter Strasse|-|-|-|11.76592|49.04841|-|-| +-|-|17|-|92345|Mühlbach|92345|Riedenburger Strasse|-|-|-|11.61610|49.02190|-|-| +-|-|17|-|92345|Dietfurt An Der Altmühl|-|-|-|-|-|11.58767|49.03485|-|-| diff --git a/reference/route/stmsdf-route.sdf b/reference/route/stmsdf-route.sdf new file mode 100644 index 000000000..e6c0ab814 --- /dev/null +++ b/reference/route/stmsdf-route.sdf @@ -0,0 +1,18 @@ +[HEADER] +FILEVERSION=1 +SOURCE=FILE +DATUM=WGS84 +TYPE=5 +DISTANCE=394 +NAME=NARVA to Jahnstrasse +[POINTS] +"WP","NARVA",50.49261597,12.10544807,391 +"WP","001",50.49260315,12.10543080,0 +"WP","002",50.49260315,12.10543080,0 +"WP","003",50.49427684,12.10513039,0 +"WP","004",50.49383394,12.10610052,0 +"WP","Liebknechtstrasse",50.49383403,12.10610026,0 +"WP","005",50.49383394,12.10610052,0 +"WP","006",50.49337562,12.10710450,0 +"WP","007",50.49365977,12.10715177,0 +"WP","Jahnstrasse",50.49366664,12.10715001,0 diff --git a/reference/route/stmwpp-route.gpx b/reference/route/stmwpp-route.gpx new file mode 100644 index 000000000..0d1ee22ce --- /dev/null +++ b/reference/route/stmwpp-route.gpx @@ -0,0 +1,64 @@ + + + + + + + NARVA + NARVA + NARVA + + + + Liebknechtstras + Liebknechtstras + Liebknechtstras + + + + Jahnstrasse11 + Jahnstrasse11 + Jahnstrasse11 + + + + Elsterberg + Elsterberg + Elsterberg + + + + Greiz + Greiz + Greiz + + + + Gosel + Gosel + Gosel + + + + 3 + 3 + 3 + + + + Altenburg-Umgehung + Altenburg-Umgehung + Altenburg-Umgehung + + + + Völkerschlachtdenkmal + Völkerschlachtdenkmal + Völkerschlachtdenkmal + + diff --git a/reference/route/stmwpp-route.txt b/reference/route/stmwpp-route.txt new file mode 100644 index 000000000..66a200c9c --- /dev/null +++ b/reference/route/stmwpp-route.txt @@ -0,0 +1,10 @@ +Datum,WGS 84,WGS 84,0,0,0,0,0 +WP,D,NARVA,50.4926189,12.1054487,09/03/2005,00:00:00.90, +WP,D,Liebknechtstras,50.4938369,12.106101,09/03/2005,00:00:00.90, +WP,D,Jahnstrasse11,50.4936628,12.1071524,09/03/2005,00:00:00.90, +WP,D,Elsterberg,50.6107952,12.1738022,09/03/2005,00:00:00.90, +WP,D,Greiz,50.654763,12.2049567,09/03/2005,00:00:00.90, +WP,D,Gosel,50.8441256,12.4087572,09/03/2005,00:00:00.90, +WP,D,3,50.8773405,12.4338887,09/03/2005,00:00:00.90, +WP,D,Altenburg-Umgehung,50.9649551,12.4359193,09/03/2005,00:00:00.90, +WP,D,Völkerschlachtdenkmal,51.3145207,12.4091433,09/03/2005,00:00:00.90, diff --git a/reference/route/tef_xml.sample.gpx b/reference/route/tef_xml.sample.gpx index 969fcc283..f9e687095 100644 --- a/reference/route/tef_xml.sample.gpx +++ b/reference/route/tef_xml.sample.gpx @@ -1,4 +1,4 @@ - + - + in Zedtwitz halb rechts halten auf B2 Hofer Strasse B2 Hofer Strasse B2 Hofer Strasse - bei D 95183 Töpen + bei D 95183 Töpen B2\Hofer Strasse B2\Hofer Strasse @@ -43,12 +43,12 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ L2357 - bei D 07907 Schleiz/Möschlitz + bei D 07907 Schleiz/Möschlitz L2357 L2357 - bei D 07924 Ziegenrück + bei D 07924 Ziegenrück L2350\Plothental L2350\Plothental @@ -64,13 +64,13 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ bei D 07907 Schleiz/Langenbuch - K304\Lössauer Strasse - K304\Lössauer Strasse + K304\Lössauer Strasse + K304\Lössauer Strasse bei D 07952 Pausa/Oberreichenau - S316\Am Mühlgraben - S316\Am Mühlgraben + S316\Am Mühlgraben + S316\Am Mühlgraben bei D 08548 Syrau @@ -78,7 +78,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B282/E49\Hauptstrasse - bei D 08525 Plauen/Preißelpöhl + bei D 08525 Plauen/Preißelpöhl Martin-Luther-Strasse Martin-Luther-Strasse @@ -88,14 +88,14 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173\Hauptstrasse - bei D 08543 Pöhl/Helmsgrün - K7880\Helmsgrün-Dorfstrasse - K7880\Helmsgrün-Dorfstrasse + bei D 08543 Pöhl/Helmsgrün + K7880\Helmsgrün-Dorfstrasse + K7880\Helmsgrün-Dorfstrasse - bei D 08543 Herlasgrün - K7811\Herlasgrün-Dorfstrasse - K7811\Herlasgrün-Dorfstrasse + bei D 08543 Herlasgrün + K7811\Herlasgrün-Dorfstrasse + K7811\Herlasgrün-Dorfstrasse bei D 07985 Elsterberg/Reuth @@ -128,7 +128,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173 - D 08115 Schönfels + D 08115 Schönfels K9351\Zwickauer Strasse K9351\Zwickauer Strasse @@ -154,23 +154,23 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ bei D 08209 Auerbach - B169\Göltzschtalstrasse - B169\Göltzschtalstrasse + B169\Göltzschtalstrasse + B169\Göltzschtalstrasse bei D 08209 Auerbach/Beerheide - K7833\Rempesgrüner Strasse - K7833\Rempesgrüner Strasse + K7833\Rempesgrüner Strasse + K7833\Rempesgrüner Strasse - D 08304 Schönheide + D 08304 Schönheide S278\Hauptstrasse S278\Hauptstrasse - bei D 08262 Tannenbergsthal/Jägersgrün - B283\Schönheider Strasse - B283\Schönheider Strasse + bei D 08262 Tannenbergsthal/Jägersgrün + B283\Schönheider Strasse + B283\Schönheider Strasse bei D 08262 Tannenbergsthal @@ -178,22 +178,22 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B283\Klingenthaler Strasse - bei D 08248 Klingenthal/Brunndöbra + bei D 08248 Klingenthal/Brunndöbra S304\Falkensteiner Strasse S304\Falkensteiner Strasse - bei D 08223 Grünbach-Muldenberg + bei D 08223 Grünbach-Muldenberg S302/S304 S302/S304 - bei D 08223 Grünbach + bei D 08223 Grünbach S304\Bahnhofstrasse S304\Bahnhofstrasse - bei D 08261 Schöneck + bei D 08261 Schöneck S301 S301 @@ -203,7 +203,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B283 - bei D 08258 Landwüst + bei D 08258 Landwüst K7844\Rauner Strasse K7844\Rauner Strasse @@ -223,7 +223,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ K7854\Oelsnitzer Strasse - bei D 08538 Burgstein/Dröda + bei D 08538 Burgstein/Dröda S310\Bobenneukirchener Strasse S310\Bobenneukirchener Strasse @@ -256,7 +256,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B2 - bei D 95183 Töpen + bei D 95183 Töpen B2\Hofer Strasse B2\Hofer Strasse @@ -289,19 +289,19 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ rechts abbiegen - in Schönbrunn links abbiegen auf Schönbrunn - Schönbrunn - Schönbrunn + in Schönbrunn links abbiegen auf Schönbrunn + Schönbrunn + Schönbrunn - links abbiegen auf Schönbrunn - Schönbrunn - Schönbrunn + links abbiegen auf Schönbrunn + Schönbrunn + Schönbrunn - halb rechts halten auf Schönbrunn - Schönbrunn - Schönbrunn + halb rechts halten auf Schönbrunn + Schönbrunn + Schönbrunn geradeaus weiter auf L1095 @@ -415,7 +415,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ L2357 - bei D 07907 Schleiz/Möschlitz + bei D 07907 Schleiz/Möschlitz L2357 L2357 @@ -423,9 +423,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ links abbiegen - in Grochwitz halb rechts halten auf Mühlenstrasse - Mühlenstrasse - Mühlenstrasse + in Grochwitz halb rechts halten auf Mühlenstrasse + Mühlenstrasse + Mühlenstrasse geradeaus weiter auf Sackgasse @@ -461,7 +461,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ L1103 - in Ziegenrück halb links halten auf Schleizer Strasse (L1103) + in Ziegenrück halb links halten auf Schleizer Strasse (L1103) Schleizer Strasse (L1103) Schleizer Strasse (L1103) @@ -471,7 +471,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Plothental (L2350) - bei D 07924 Ziegenrück + bei D 07924 Ziegenrück L2350\Plothental L2350\Plothental @@ -526,25 +526,25 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B2 - in Oettersdorf links abbiegen auf Löhmaer Weg (K301) - Löhmaer Weg (K301) - Löhmaer Weg (K301) + in Oettersdorf links abbiegen auf Löhmaer Weg (K301) + Löhmaer Weg (K301) + Löhmaer Weg (K301) - rechts abbiegen auf Löhmaer Weg (K301) - Löhmaer Weg (K301) - Löhmaer Weg (K301) + rechts abbiegen auf Löhmaer Weg (K301) + Löhmaer Weg (K301) + Löhmaer Weg (K301) - links abbiegen auf Löhmaer Weg (K301) - Löhmaer Weg (K301) - Löhmaer Weg (K301) + links abbiegen auf Löhmaer Weg (K301) + Löhmaer Weg (K301) + Löhmaer Weg (K301) rechts abbiegen - in Löhma links abbiegen auf Ortsstrasse + in Löhma links abbiegen auf Ortsstrasse Ortsstrasse Ortsstrasse @@ -592,12 +592,12 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Dorfstrasse - in Lössau links abbiegen + in Lössau links abbiegen bei D 07907 Schleiz/Langenbuch - K304\Lössauer Strasse - K304\Lössauer Strasse + K304\Lössauer Strasse + K304\Lössauer Strasse in Langenbuch links abbiegen auf Thierbacher Strasse (L2348) @@ -616,14 +616,14 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Plauensche Strasse (S316) - in Oberreichenau halb links halten auf Am Mühlgraben (S316) - Am Mühlgraben (S316) - Am Mühlgraben (S316) + in Oberreichenau halb links halten auf Am Mühlgraben (S316) + Am Mühlgraben (S316) + Am Mühlgraben (S316) bei D 07952 Pausa/Oberreichenau - S316\Am Mühlgraben - S316\Am Mühlgraben + S316\Am Mühlgraben + S316\Am Mühlgraben in Syrau halb rechts halten auf B282/E49 Hauptstrasse @@ -651,7 +651,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Martin-Luther-Strasse - bei D 08525 Plauen/Preißelpöhl + bei D 08525 Plauen/Preißelpöhl Martin-Luther-Strasse Martin-Luther-Strasse @@ -666,9 +666,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173 Hammerstrasse - links abbiegen auf Voigtsgrüner Weg (K6605) - Voigtsgrüner Weg (K6605) - Voigtsgrüner Weg (K6605) + links abbiegen auf Voigtsgrüner Weg (K6605) + Voigtsgrüner Weg (K6605) + Voigtsgrüner Weg (K6605) rechts abbiegen auf Zum Plom @@ -709,17 +709,17 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173 Hauptstrasse - links abbiegen auf Gansgrüner Strasse (K7880) - Gansgrüner Strasse (K7880) - Gansgrüner Strasse (K7880) + links abbiegen auf Gansgrüner Strasse (K7880) + Gansgrüner Strasse (K7880) + Gansgrüner Strasse (K7880) - links abbiegen auf Gansgrüner Strasse (K7880) - Gansgrüner Strasse (K7880) - Gansgrüner Strasse (K7880) + links abbiegen auf Gansgrüner Strasse (K7880) + Gansgrüner Strasse (K7880) + Gansgrüner Strasse (K7880) - in Gansgrün links abbiegen auf Dorfstrasse + in Gansgrün links abbiegen auf Dorfstrasse Dorfstrasse Dorfstrasse @@ -737,37 +737,37 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ halb links halten - bei D 08543 Pöhl/Helmsgrün - K7880\Helmsgrün-Dorfstrasse - K7880\Helmsgrün-Dorfstrasse + bei D 08543 Pöhl/Helmsgrün + K7880\Helmsgrün-Dorfstrasse + K7880\Helmsgrün-Dorfstrasse - in Helmsgrün halb rechts halten + in Helmsgrün halb rechts halten - in Herlasgrün rechts abbiegen auf Herlasgrün-Dorfstrasse (K7811) - Herlasgrün-Dorfstrasse (K7811) - Herlasgrün-Dorfstrasse (K7811) + in Herlasgrün rechts abbiegen auf Herlasgrün-Dorfstrasse (K7811) + Herlasgrün-Dorfstrasse (K7811) + Herlasgrün-Dorfstrasse (K7811) - bei D 08543 Herlasgrün - K7811\Herlasgrün-Dorfstrasse - K7811\Herlasgrün-Dorfstrasse + bei D 08543 Herlasgrün + K7811\Herlasgrün-Dorfstrasse + K7811\Herlasgrün-Dorfstrasse - links abbiegen auf Herlasgrün-Christgrüner Strasse - Herlasgrün-Christgrüner Strasse - Herlasgrün-Christgrüner Strasse + links abbiegen auf Herlasgrün-Christgrüner Strasse + Herlasgrün-Christgrüner Strasse + Herlasgrün-Christgrüner Strasse - geradeaus weiter auf Christgrüner Strasse - Christgrüner Strasse - Christgrüner Strasse + geradeaus weiter auf Christgrüner Strasse + Christgrüner Strasse + Christgrüner Strasse - rechts abbiegen auf Dreckschänke (S297) - Dreckschänke (S297) - Dreckschänke (S297) + rechts abbiegen auf Dreckschänke (S297) + Dreckschänke (S297) + Dreckschänke (S297) links abbiegen auf S298 @@ -775,13 +775,13 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ S298 - in Reimersgrün links abbiegen + in Reimersgrün links abbiegen halb rechts halten - in Coschütz rechts abbiegen auf Friedensstrasse (K7887) + in Coschütz rechts abbiegen auf Friedensstrasse (K7887) Friedensstrasse (K7887) Friedensstrasse (K7887) @@ -841,9 +841,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173/B94 Klinkhardtstrasse - links abbiegen auf B173/B94 Dr.-Külz-Strasse - B173/B94 Dr.-Külz-Strasse - B173/B94 Dr.-Külz-Strasse + links abbiegen auf B173/B94 Dr.-Külz-Strasse + B173/B94 Dr.-Külz-Strasse + B173/B94 Dr.-Külz-Strasse rechts abbiegen auf B173 Friedensstrasse @@ -871,7 +871,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173 - in Schönfels links abbiegen auf Stenner Strasse + in Schönfels links abbiegen auf Stenner Strasse Stenner Strasse Stenner Strasse @@ -881,7 +881,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Zwickauer Strasse (K9351) - D 08115 Schönfels + D 08115 Schönfels K9351\Zwickauer Strasse K9351\Zwickauer Strasse @@ -916,9 +916,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173 Dr.-Friedrichs-Ring - geradeaus weiter auf B173 Glück-Auf-Brücke/Äussere Dresdner Strasse - B173 Glück-Auf-Brücke/Äussere Dresdner Strasse - B173 Glück-Auf-Brücke/Äussere Dresdner Strasse + geradeaus weiter auf B173 Glück-Auf-Brücke/Äussere Dresdner Strasse + B173 Glück-Auf-Brücke/Äussere Dresdner Strasse + B173 Glück-Auf-Brücke/Äussere Dresdner Strasse rechts abbiegen auf Dresdner Strasse @@ -926,9 +926,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Dresdner Strasse - geradeaus weiter auf Äussere Zwickauer Strasse - Äussere Zwickauer Strasse - Äussere Zwickauer Strasse + geradeaus weiter auf Äussere Zwickauer Strasse + Äussere Zwickauer Strasse + Äussere Zwickauer Strasse in Lichtenstein/Sa. geradeaus weiter auf Innere Zwickauer Strasse @@ -1050,12 +1050,12 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B169 Kobaltstrasse - in Hundshübel halb rechts halten auf B169 Hauptstrasse + in Hundshübel halb rechts halten auf B169 Hauptstrasse B169 Hauptstrasse B169 Hauptstrasse - in Stützengrün rechts abbiegen auf B169 Auerbacher Strasse + in Stützengrün rechts abbiegen auf B169 Auerbacher Strasse B169 Auerbacher Strasse B169 Auerbacher Strasse @@ -1076,13 +1076,13 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ bei D 08209 Auerbach - B169\Göltzschtalstrasse - B169\Göltzschtalstrasse + B169\Göltzschtalstrasse + B169\Göltzschtalstrasse - in Auerbach/Vogtl. links abbiegen auf B169 Göltzschtalstrasse - B169 Göltzschtalstrasse - B169 Göltzschtalstrasse + in Auerbach/Vogtl. links abbiegen auf B169 Göltzschtalstrasse + B169 Göltzschtalstrasse + B169 Göltzschtalstrasse in Ellefeld links abbiegen auf Neuberg @@ -1106,8 +1106,8 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ bei D 08209 Auerbach/Beerheide - K7833\Rempesgrüner Strasse - K7833\Rempesgrüner Strasse + K7833\Rempesgrüner Strasse + K7833\Rempesgrüner Strasse in Beerheide links abbiegen auf Strasse des Friedens (K7826) @@ -1115,7 +1115,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Strasse des Friedens (K7826) - in Hohengrün rechts abbiegen auf Klingenthaler Strasse (S300) + in Hohengrün rechts abbiegen auf Klingenthaler Strasse (S300) Klingenthaler Strasse (S300) Klingenthaler Strasse (S300) @@ -1128,17 +1128,17 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Schallerbachstrasse (K7822) - in Brunn rechts abbiegen auf Schönheider Strasse (S278) - Schönheider Strasse (S278) - Schönheider Strasse (S278) + in Brunn rechts abbiegen auf Schönheider Strasse (S278) + Schönheider Strasse (S278) + Schönheider Strasse (S278) - in Schönheide halb rechts halten auf Hauptstrasse (S278) + in Schönheide halb rechts halten auf Hauptstrasse (S278) Hauptstrasse (S278) Hauptstrasse (S278) - D 08304 Schönheide + D 08304 Schönheide S278\Hauptstrasse S278\Hauptstrasse @@ -1163,14 +1163,14 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Am Filz - geradeaus weiter auf B283 Schönheider Strasse - B283 Schönheider Strasse - B283 Schönheider Strasse + geradeaus weiter auf B283 Schönheider Strasse + B283 Schönheider Strasse + B283 Schönheider Strasse - bei D 08262 Tannenbergsthal/Jägersgrün - B283\Schönheider Strasse - B283\Schönheider Strasse + bei D 08262 Tannenbergsthal/Jägersgrün + B283\Schönheider Strasse + B283\Schönheider Strasse bei D 08262 Tannenbergsthal @@ -1193,12 +1193,12 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Falkensteiner Strasse (S304) - bei D 08248 Klingenthal/Brunndöbra + bei D 08248 Klingenthal/Brunndöbra S304\Falkensteiner Strasse S304\Falkensteiner Strasse - bei D 08223 Grünbach-Muldenberg + bei D 08223 Grünbach-Muldenberg S302/S304 S302/S304 @@ -1208,37 +1208,37 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ S304 - bei D 08223 Grünbach + bei D 08223 Grünbach S304\Bahnhofstrasse S304\Bahnhofstrasse - in Grünbach links abbiegen auf Neustädter Strasse (K7835) - Neustädter Strasse (K7835) - Neustädter Strasse (K7835) + in Grünbach links abbiegen auf Neustädter Strasse (K7835) + Neustädter Strasse (K7835) + Neustädter Strasse (K7835) - links abbiegen auf Siehdichfürer Strasse (K7835) - Siehdichfürer Strasse (K7835) - Siehdichfürer Strasse (K7835) + links abbiegen auf Siehdichfürer Strasse (K7835) + Siehdichfürer Strasse (K7835) + Siehdichfürer Strasse (K7835) - in Neudorf links abbiegen auf Schönecker Strasse (S301) - Schönecker Strasse (S301) - Schönecker Strasse (S301) + in Neudorf links abbiegen auf Schönecker Strasse (S301) + Schönecker Strasse (S301) + Schönecker Strasse (S301) - links abbiegen auf Schönecker Strasse (S301) - Schönecker Strasse (S301) - Schönecker Strasse (S301) + links abbiegen auf Schönecker Strasse (S301) + Schönecker Strasse (S301) + Schönecker Strasse (S301) - bei D 08261 Schöneck + bei D 08261 Schöneck S301 S301 - in Schöneck/Vogtl. rechts abbiegen auf Falkensteiner Strasse (S301/S302) + in Schöneck/Vogtl. rechts abbiegen auf Falkensteiner Strasse (S301/S302) Falkensteiner Strasse (S301/S302) Falkensteiner Strasse (S301/S302) @@ -1256,9 +1256,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ einfahren in Kreisverkehr - 2. Möglichkeit aus Kreisverkehr ausfahren auf Kärnerstrasse (S305) - Kärnerstrasse (S305) - Kärnerstrasse (S305) + 2. Möglichkeit aus Kreisverkehr ausfahren auf Kärnerstrasse (S305) + Kärnerstrasse (S305) + Kärnerstrasse (S305) rechts abbiegen auf B283 @@ -1281,9 +1281,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Am Bahnhof - links abbiegen auf Strässler Berg - Strässler Berg - Strässler Berg + links abbiegen auf Strässler Berg + Strässler Berg + Strässler Berg geradeaus weiter auf Siebenbrunner Strasse @@ -1291,24 +1291,24 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Siebenbrunner Strasse - in Strässel links abbiegen auf Böhmische Strasse (K7846) - Böhmische Strasse (K7846) - Böhmische Strasse (K7846) + in Strässel links abbiegen auf Böhmische Strasse (K7846) + Böhmische Strasse (K7846) + Böhmische Strasse (K7846) - in Schönlind rechts abbiegen auf Markneukirchner Strasse (K7843) + in Schönlind rechts abbiegen auf Markneukirchner Strasse (K7843) Markneukirchner Strasse (K7843) Markneukirchner Strasse (K7843) - links abbiegen auf Landwüster Strasse (K7846) - Landwüster Strasse (K7846) - Landwüster Strasse (K7846) + links abbiegen auf Landwüster Strasse (K7846) + Landwüster Strasse (K7846) + Landwüster Strasse (K7846) - in Landwüst halb rechts halten auf Schönlinder Strasse (K7844) - Schönlinder Strasse (K7844) - Schönlinder Strasse (K7844) + in Landwüst halb rechts halten auf Schönlinder Strasse (K7844) + Schönlinder Strasse (K7844) + Schönlinder Strasse (K7844) rechts abbiegen auf Rauner Strasse (K7844) @@ -1316,7 +1316,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Rauner Strasse (K7844) - bei D 08258 Landwüst + bei D 08258 Landwüst K7844\Rauner Strasse K7844\Rauner Strasse @@ -1403,7 +1403,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ links abbiegen - in Bösenbrunn rechts abbiegen auf S310 + in Bösenbrunn rechts abbiegen auf S310 S310 S310 @@ -1413,7 +1413,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ S310 - in Dröda rechts abbiegen auf Hauptstrasse/Bobenneukirchener Strasse (S310) + in Dröda rechts abbiegen auf Hauptstrasse/Bobenneukirchener Strasse (S310) Hauptstrasse/Bobenneukirchener Strasse (S310) Hauptstrasse/Bobenneukirchener Strasse (S310) @@ -1423,7 +1423,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Bobenneukirchener Strasse (S310) - bei D 08538 Burgstein/Dröda + bei D 08538 Burgstein/Dröda S310\Bobenneukirchener Strasse S310\Bobenneukirchener Strasse @@ -1433,9 +1433,9 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ B173 Hofer Strasse - links abbiegen auf Zur Pirkmühle (K7859) - Zur Pirkmühle (K7859) - Zur Pirkmühle (K7859) + links abbiegen auf Zur Pirkmühle (K7859) + Zur Pirkmühle (K7859) + Zur Pirkmühle (K7859) bei D 08538 Burgstein/Pirk @@ -1479,7 +1479,7 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ links abbiegen - in Heinersgrün halb links halten auf An der Kapelle (K7855) + in Heinersgrün halb links halten auf An der Kapelle (K7855) An der Kapelle (K7855) An der Kapelle (K7855) diff --git a/reference/sample.gtm b/reference/sample.gtm new file mode 100644 index 0000000000000000000000000000000000000000..3ba596fdb21ab124877af0307e95b979223b1daa GIT binary patch literal 90544 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 XbJTzSm4^GAGcxDq%t_0=M$Y7Kd~fl7 literal 0 HcmV?d00001 diff --git a/reference/stmsdf.txt b/reference/stmsdf.txt new file mode 100644 index 000000000..1f345153d --- /dev/null +++ b/reference/stmsdf.txt @@ -0,0 +1,83 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint 001 User Waypoint N50 29.56 E12 06.33 0 m Symbol & Name Unknown Waypoint +Waypoint 002 User Waypoint N50 29.56 E12 06.33 0 m Symbol & Name Unknown Waypoint +Waypoint 003 User Waypoint N50 29.66 E12 06.31 0 m Symbol & Name Unknown Waypoint +Waypoint 004 User Waypoint N50 29.63 E12 06.37 0 m Symbol & Name Unknown Waypoint +Waypoint 005 User Waypoint N50 29.63 E12 06.37 0 m Symbol & Name Unknown Waypoint +Waypoint 006 User Waypoint N50 29.60 E12 06.43 0 m Symbol & Name Unknown Waypoint +Waypoint 007 User Waypoint N50 29.62 E12 06.43 0 m Symbol & Name Unknown Waypoint +Waypoint Jahnstrasse User Waypoint N50 29.62 E12 06.43 0 m Symbol & Name Unknown Waypoint +Waypoint Liebknechtstrasse User Waypoint N50 29.63 E12 06.37 0 m Symbol & Name Unknown Waypoint +Waypoint NARVA User Waypoint N50 29.56 E12 06.33 391 m Symbol & Name Unknown Waypoint + + +Header Name Length Course Waypoints Link + +Route 394 m 46° true 10 waypoints + +Header Waypoint Name Distance Leg Length Course + +Route Waypoint NARVA 0 m +Route Waypoint 001 2 m 2 m 221° true +Route Waypoint 002 2 m 0 m 0° true +Route Waypoint 003 189 m 188 m 353° true +Route Waypoint 004 274 m 85 m 126° true +Route Waypoint Liebknechtstrasse 274 m 0 m 299° true +Route Waypoint 005 274 m 0 m 119° true +Route Waypoint 006 361 m 88 m 126° true +Route Waypoint 007 393 m 32 m 6° true +Route Waypoint Jahnstrasse 394 m 1 m 351° true + + +Header Name Start Time Elapsed Time Length Average Speed Link + +Track ACTIVE LOG 006 01/05/2005 15:02:47 0:33:09 653 m 1.2 kph + +Header Position Time Altitude Depth Leg Length Leg Time Leg Speed Leg Course + +Trackpoint N51 18.78 E12 24.79 01/05/2005 15:02:47 161 m 0.0 m +Trackpoint N51 18.77 E12 24.79 01/05/2005 15:03:25 154 m 0.0 m 8 m 0:00:38 0.8 kph 137° true +Trackpoint N51 18.77 E12 24.79 01/05/2005 15:03:39 148 m 0.0 m 3 m 0:00:14 0.8 kph 180° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:04:16 139 m 0.0 m 5 m 0:00:37 0.5 kph 129° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:05:02 145 m 0.0 m 2 m 0:00:46 0.2 kph 270° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:05:45 134 m 0.0 m 2 m 0:00:43 0.2 kph 90° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:06:44 131 m 0.0 m 6 m 0:00:59 0.4 kph 162° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:07:50 130 m 0.0 m 0 m 0:01:06 0 kph 0° true +Trackpoint N51 18.76 E12 24.80 01/05/2005 15:08:19 132 m 0.0 m 3 m 0:00:29 0.4 kph 180° true +Trackpoint N51 18.77 E12 24.80 01/05/2005 15:11:16 144 m 0.0 m 6 m 0:02:57 0.1 kph 342° true +Trackpoint N51 18.77 E12 24.81 01/05/2005 15:12:34 147 m 0.0 m 16 m 0:01:18 0.7 kph 38° true +Trackpoint N51 18.78 E12 24.83 01/05/2005 15:13:18 145 m 0.0 m 27 m 0:00:44 2 kph 70° true +Trackpoint N51 18.78 E12 24.83 01/05/2005 15:13:27 145 m 0.0 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.78 E12 24.83 01/05/2005 15:13:37 135 m 0.0 m 2 m 0:00:10 0.7 kph 90° true +Trackpoint N51 18.79 E12 24.83 01/05/2005 15:13:46 135 m 0.0 m 6 m 0:00:09 2 kph 0° true +Trackpoint N51 18.79 E12 24.83 01/05/2005 15:14:03 136 m 0.0 m 13 m 0:00:17 3 kph 17° true +Trackpoint N51 18.80 E12 24.84 01/05/2005 15:14:16 135 m 0.0 m 11 m 0:00:13 3 kph 32° true +Trackpoint N51 18.80 E12 24.84 01/05/2005 15:14:26 139 m 0.0 m 7 m 0:00:10 2 kph 117° true +Trackpoint N51 18.80 E12 24.85 01/05/2005 15:14:30 139 m 0.0 m 4 m 0:00:04 4 kph 90° true +Trackpoint N51 18.78 E12 24.88 01/05/2005 15:15:06 141 m 0.0 m 43 m 0:00:36 4 kph 126° true +Trackpoint N51 18.78 E12 24.89 01/05/2005 15:15:27 140 m 0.0 m 18 m 0:00:21 3 kph 121° true +Trackpoint N51 18.77 E12 24.90 01/05/2005 15:15:39 140 m 0.0 m 10 m 0:00:12 3 kph 128° true +Trackpoint N51 18.78 E12 24.90 01/05/2005 15:25:31 152 m 0.0 m 4 m 0:09:52 0.0 kph 33° true +Trackpoint N51 18.78 E12 24.90 01/05/2005 15:25:40 152 m 0.0 m 0 m 0:00:09 0 kph 0° true +Trackpoint N51 18.78 E12 24.90 01/05/2005 15:29:18 155 m 0.0 m 4 m 0:03:38 0.1 kph 328° true +Trackpoint N51 18.79 E12 24.87 01/05/2005 15:30:30 149 m 0.0 m 33 m 0:01:12 2 kph 311° true +Trackpoint N51 18.79 E12 24.87 01/05/2005 15:30:37 150 m 0.0 m 2 m 0:00:07 1.0 kph 270° true +Trackpoint N51 18.79 E12 24.87 01/05/2005 15:30:47 151 m 0.0 m 8 m 0:00:10 3 kph 270° true +Trackpoint N51 18.79 E12 24.86 01/05/2005 15:30:48 151 m 0.0 m 4 m 0:00:01 14 kph 270° true +Trackpoint N51 18.80 E12 24.83 01/05/2005 15:30:52 150 m 0.0 m 38 m 0:00:04 34 kph 300° true +Trackpoint N51 18.82 E12 24.80 01/05/2005 15:30:57 150 m 0.0 m 57 m 0:00:05 41 kph 315° true +Trackpoint N51 18.84 E12 24.77 01/05/2005 15:31:03 150 m 0.0 m 47 m 0:00:06 28 kph 316° true +Trackpoint N51 18.85 E12 24.75 01/05/2005 15:31:10 150 m 0.0 m 35 m 0:00:07 18 kph 314° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:32:38 143 m 0.0 m 210 m 0:01:28 9 kph 283° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:32:45 141 m 0.0 m 4 m 0:00:07 2 kph 270° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:33:17 143 m 0.0 m 0 m 0:00:32 0 kph 0° true +Trackpoint N51 18.88 E12 24.57 01/05/2005 15:33:42 139 m 0.0 m 4 m 0:00:25 0.6 kph 270° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:33:54 139 m 0.0 m 6 m 0:00:12 2 kph 270° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:34:04 138 m 0.0 m 0 m 0:00:10 0 kph 0° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:34:20 139 m 0.0 m 0 m 0:00:16 0 kph 0° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:35:45 144 m 0.0 m 0 m 0:01:25 0 kph 0° true +Trackpoint N51 18.88 E12 24.56 01/05/2005 15:35:56 145 m 0.0 m 0 m 0:00:11 0 kph 0° true diff --git a/reference/tpo-sample.tpo b/reference/tpo-sample.tpo new file mode 100644 index 0000000000000000000000000000000000000000..6c3751e1fd8537037ac773aeca3f299839c68f54 GIT binary patch literal 9293 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 + + + + 2428.000000 + 001 + 001 + 001 + + + 2439.000000 + 002 + 002 + 002 + + + 2462.000000 + 003 + WITH MESSAGE + WITH MESSAGE + + + 2559.000000 + GPSRTE0 + GPSRTE0 + GPSRTE0 + + + 2582.000000 + GPSRTE1 + GPSRTE1 + GPSRTE1 + + + 2586.000000 + GPSRTE2 + GPSRTE2 + GPSRTE2 + + + 2612.000000 + GPSRTE3 + GPSRTE3 + GPSRTE3 + + + 2606.000000 + GPSRTE4 + GPSRTE4 + GPSRTE4 + + + 2632.000000 + GPSRTE5 + GPSRTE5 + GPSRTE5 + + + 2627.000000 + GPSRTE6 + GPSRTE6 + GPSRTE6 + + + 2622.000000 + GPSRTE7 + GPSRTE7 + GPSRTE7 + + + 2639.000000 + GPSRTE8 + GPSRTE8 + GPSRTE8 + + + 2599.000000 + GPSRTE9 + GPSRTE9 + GPSRTE9 + + + NOTE 1 + This is a note that has a photo attached + This is a note that has a photo attached + w:\photo.jpg + + + NOTE 2 + 2nd note, with link to a web page + 2nd note, with link to a web page + http://www.defghi.org + + + NOTE 3 + 3rd note, with a link to a document + 3rd note, with a link to a document + c:document.txt + + + SYM 1 + SYM 1 + SYM 1 + + + SYM 2 + SYM 2 + SYM 2 + + + SYM 3 + SYM 3 + SYM 3 + + + SYM 4 + SYM 4 + SYM 4 + + + TXT 1 + test + test + + + TXT 2 + test2 with new style + test2 with new style + + + TXT 3 + 2.55 miles + 2.55 miles + + + RTE 1 + 1 + + 2559.000000 + GPSRTE0 + + + 2582.000000 + GPSRTE1 + + + 2586.000000 + GPSRTE2 + + + 2612.000000 + GPSRTE3 + + + 2606.000000 + GPSRTE4 + + + 2632.000000 + GPSRTE5 + + + 2627.000000 + GPSRTE6 + + + 2622.000000 + GPSRTE7 + + + 2639.000000 + GPSRTE8 + + + 2599.000000 + GPSRTE9 + + + + crazy route 4.49 miles long +1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TRK 2 +2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TRK 3 +3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/tpo-sample3.tpo b/reference/tpo-sample3.tpo new file mode 100644 index 0000000000000000000000000000000000000000..af5065a45f21e53e1351db458cf04177fc801f80 GIT binary patch literal 7442 zcmeI1eQXrR6~O1t_p!HoJA3xp2N*~enxq)f!yktM2SRK(J{;Rv_5lVVhqZ6k>z2t{hssA{XGv~s25QeyYb z?t+(t{?)(I-ipJ&dGF1e_c1$%hfsWL=hj8ic14Xy4UuT10hONrw+j5o{e{Wcg-%1T zk9#|Eno@wM1E|K2P#M}Yk0WotVu%v*Er};n1quGhQWmTvEh%eKQl{g4GN@0vp{CuYDDqH#V0d`?NZHKAnct#N>&7h`zc3Xk1zM`W|7Hc={5eM^kI{G9yQn^! zFyH27(ojlEO6gQ~pG03}X-Mgl^74REmDIF+)AHp*Lqm~-vUebvisaM*yD%?p4U(Q$ zO;2BHP;c@iJA5T_{eu}LtKt5p>lo37wd>V&qmX!=OFv5$C{>_Tfl>uZ6)07pRDn_j z{>ut%iFIrkYuR(iS4hfvrQl*&j6!!Uwi`w2Lhbuj1i zi{-XW(Ce+LvYGdKs=_wofFD=bEPzd=%^}lXR@K~)8Gq1cv76&q)@F!5$l2_1$Z7o7 z?R^e8#DBw{amWK46A)}aP^laKIffGgwmj&N^A3CLkP8m`5S6p4(yuDAmda&aK1K{V z#%?bYc8<%~KoC3h9>yzFImTXppxmkVm9f>FL+?kNT*$b=tK}iMIkhj99gxfjXT?H$ZZNCKsjSpu>aA+}(Y7#x zy#y=66LbmjR7NRC9my0Rm-LyE_G;!<04ORP=mj_+)X zRo)VCEktqfc9~eMDeuVj>P)d9uyG1udVYvP2Qm94p)*&V4vhH7(&v#MbB6S{#ufu8uR(wEb;*Kcj_Z0_#1 za(27zX9d%u0%PNSRdvY;Bv(a!Q4(0L5jyE2r*uzy$&9ROkvE#B_&v zP{kbjxA*FDj(pr{h{&rAa71kZa$h^jk&jjZ`I*&0^72|BrOS`n@ZRG*Su$>j)yC*io-BSI=JlTDiT*8ssSkK^_z1w*Wu6>51aNi@CI?i2 z$)_;c-v{vAc}yPe0$BVBCR!`NsVmsb%&7bgCTmuL351%T~-OltiA z?2mb}?8=B}9C#iA`YQm<=c(TVq~GDmuHOMrWXcb=nCBWVSPmY}cczYL5g0BIDTX@30 z1kiOiPnc0%eBq6;01G>0B#Nd3uCZ$Z>3wH*8@yobzaS8D8oK^;O@=i-`ldjnXQ1Ns zae*v24A9jem`#1dcyzU3b@iD(feh~g9T^v_9=`l*!Q7mgd8UVR3@C?t1!BVHpg`V3 zAo);&#U~-z*2e_0{e1wsxY?Mt%Qm$9N+2hHK`V32hVf>Bj2{Qdb}X13x@5e2hhR12 zt}emq!=Wbx(%1z?cvK+KR)C3b2qaPupnY8+yBCg#SO3Hso`OI+|DuckoPdhl5k~u} z7xLt@8h!S)pn_A4x)?UjuHebp4qa@Nm)0~rU}%FpIdU%yW83yDU0Rdb6OYCFcN_Gj zk-nmfJ2P@D))?zcHyN!DV{-ByU2Mwa;>NKbU@{TW#V^MYV$j<8^mX;0@8HPd3nStr z94=SjL%$CL^Z=mW$jE(ghBM1^5>)?y&t_1u@TsKgdh245p6uo~9C97s3w^n$i=W!w z7TVs}`pAkE)+qp|6M6#Hc0t-3m?i6TnY>(p|7f5mk5n6p)>1PVYf@dq%1CWAp$w>s zQgDyo&5_W^h`9JXM<)KI!;yp0)ddLgkVb879a{4sN1~7E;SC20B^2BJ+#YZQLbq&Zo%eLua@3mrG6wN)slgo9wIR9#~ zZUs90M>uI7(8V5)rzn<2^zIx?7A(}osJmFV65YQQlPA~fVjG<3H|MYlEqE4Q=`hUm k7wcA|Yd^tcvRN0`UAYm903D^xgNOBaeSRhY{|M**4ev-gNdN!< literal 0 HcmV?d00001 diff --git a/reference/track/axim-sample.gpb b/reference/track/axim-sample.gpb new file mode 100644 index 0000000000000000000000000000000000000000..ac40b00db7d73a095c06c4ef01c21dc504c6fede GIT binary patch literal 4128 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Ν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

IRjVE78z8XlhdmeaPIciheL{ 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

R6E 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∋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

Y6(gckO7Q#+ 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 U4ed0t_#JEbzJq3HmiSY`6N|IkkpKVy literal 0 HcmV?d00001 diff --git a/win32/gpsbabel.rc.in b/win32/gpsbabel.rc.in new file mode 100644 index 000000000..dbcdc4f91 --- /dev/null +++ b/win32/gpsbabel.rc.in @@ -0,0 +1,27 @@ +MAINICON ICON "@srcdir@/win32/gpsbabel.ico" + +1 VERSIONINFO +FILEVERSION @GBMAJOR@,@GBMINOR@,@GBMICRO@,0 +PRODUCTVERSION @GBMAJOR@,@GBMINOR@,@GBMICRO@,0 +FILEOS 0x4 +FILETYPE 0x1 +FILESUBTYPE 0x0L +FILEFLAGSMASK 0x3fL +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "GPSBabel Makers\0" + VALUE "FileDescription", "GPS format converter\0" + VALUE "FileVersion", "@GBMAJOR@.@GBMINOR@.@GBMICRO@@PACKAGE_RELEASE@\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "(C) 2002-2006 The people behind GPSBabel\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "gpsbabel.exe\0" + VALUE "ProductName", "GPSBabel\0" + VALUE "ProductVersion", "@GBMAJOR@.@GBMINOR@.@GBMICRO@@PACKAGE_RELEASE@\0" + VALUE "Comments", "http://www.gpsbabel.org\0" + } + } +} diff --git a/win32/gui-2/GPSBabelGUI.cfg b/win32/gui-2/GPSBabelGUI.cfg new file mode 100644 index 000000000..511e5eef3 --- /dev/null +++ b/win32/gui-2/GPSBabelGUI.cfg @@ -0,0 +1,35 @@ +-$A- +-$B- +-$C- +-$D- +-$E- +-$F- +-$G+ +-$H+ +-$I- +-$J+ +-$K- +-$L- +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V- +-$W- +-$X+ +-$Y- +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H- +-W- +-M +-$M16384,1048576 +-K$00400000 +-LNd:\borland\delphi4\Lib +-DMSWINDOWS diff --git a/win32/gui-2/GPSBabelGUI.dof b/win32/gui-2/GPSBabelGUI.dof new file mode 100644 index 000000000..57845625a --- /dev/null +++ b/win32/gui-2/GPSBabelGUI.dof @@ -0,0 +1,84 @@ +[Compiler] +A=0 +B=0 +C=0 +D=0 +E=0 +F=0 +G=1 +H=1 +I=0 +J=1 +K=0 +L=0 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=0 +W=0 +X=1 +Y=0 +Z=1 +ShowHints=0 +ShowWarnings=0 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=vcl;rtl;vclx;dbrtl;adortl;vcldb;bdertl;vcldbx;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;dsnap;vclactnband +Conditionals=MSWINDOWS +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=0 +MinorVer=2 +Release=6 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName=GPSBabel Makers +FileDescription=GPSBabel Windows Frontend +FileVersion=0.2.6.0 +InternalName= +LegalCopyright=(C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org) +LegalTrademarks= +OriginalFilename=GPSBabelGUI.exe +ProductName=GPSBabel +ProductVersion=1.3.x +Comments= +[HistoryLists\hlConditionals] +Count=1 +Item0=MSWINDOWS +[HistoryLists\hlUnitAliases] +Count=1 +Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; diff --git a/win32/gui-2/GPSBabelGUI.dpr b/win32/gui-2/GPSBabelGUI.dpr new file mode 100644 index 000000000..bd8b0f83b --- /dev/null +++ b/win32/gui-2/GPSBabelGUI.dpr @@ -0,0 +1,54 @@ +program GPSBabelGUI; +{ + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +uses + gnugettext in 'gnugettext.pas', + gnugettextDx in 'gnugettextDx.pas', + delphi in 'delphi.pas', + Windows, + SysUtils, + classes, + Forms, + main in 'main.pas' {frmMain}, + utils in 'utils.pas', + common in 'common.pas', + filter in 'filter.pas' {frmFilter}, + about in 'about.pas' {frmAbout}, + readme in 'readme.pas' {frmReadme}, + options in 'options.pas' {frmOptions}, + select in 'select.pas' {frmSelect}; + +{$R *.RES} + +var + lang: string; + +begin + AddDomainForResourceString('delphi'); + lang := ReadProfile('Global:Language', ''); + if (lang <> '') then + UseLanguage(lang); +{$IFOPT D+} +// UseLanguage('fr'); // for testing +{$ENDIF} + Application.Initialize; + Application.CreateForm(TfrmMain, frmMain); + Application.CreateForm(TfrmReadme, frmReadme); + Application.Run; +end. diff --git a/win32/gui-2/GPSBabelGUI.ico b/win32/gui-2/GPSBabelGUI.ico new file mode 100644 index 0000000000000000000000000000000000000000..76a19fd4f8255c3c2e0030659d9d33beef9973bc GIT binary patch literal 766 zcmcIiF%H5o47?(Sj!euQc?Lhjqo380p;8{vg(omXm@{cn9JL!bJ=@o_<3tM3aSg)> zZjS?SX1ovsaV0t&=>eg(Z9MIDk^== z(brrR-n7=kGZyS|FRkm94Pn1_9vj@&{Vek)X3sr76}#{0>`!K??oXB*o+4*Us85kk m*3>tg%-6o%iCjV_JZ!pdr6EWj8tB9d5%f_y{~B8rU(Sp<=Q%Vxodl@qJ^CH@N& zN(++x5n9;UT5P;N=iV81W^g+_nKSpCd*1VT@0Fw`>|9{P68*T4+eg4e-qvVbs^y?D zgeE)#M+(~sK7Xe~;!~1@g+C&k=;Y)CgB4+m3k&~Hmu;S>G*FUR>Y1LN=}MC{sTXzC zi+Y;MoN~NO0x(QBXc3>{P>NU0hl5cb&-IKU%tN))aPLcb~&FD)X|0i1x%jMj+5?`U47*0jO@p`Icw`3xIA z-#oI>m)cLtj1->P#k2LEw@NkE5Ix&q`Ru`KI#O4=YHLUHtozy~a$B!;0Opg&#G0bh zyYLh>SVc3kE@r{JRYxuGALzP;w(S!vXq8GIu(Qd|K0PiY?;&?}2;!x#;-BZ6WB*XE zd>tL?*(Gj!NSqhG)-4e4@o5sH>(NKVXlo0vSoK2e^(^NgW~>QK!qc#w-!;&Y@7ZE> ziPECtVmIPdPl9=jeaBm^^A0`RasgdjvKz#K^@PqwCH-9$+wXA{B!|Ai~fvOvKlR; z^_9=uv~XJ0vs%z|rZGXxV_0-CO4e249FXZ9=X6w>PSxLX$GUjVr+N~%$Z;D!25+|^ ozfV?Gn;dpejOP4*-S?MQKe(aNb$`3VB-(h{q>FcGwD!IB2a^tK00000 literal 0 HcmV?d00001 diff --git a/win32/gui-2/Makefile b/win32/gui-2/Makefile new file mode 100644 index 000000000..0d84bc991 --- /dev/null +++ b/win32/gui-2/Makefile @@ -0,0 +1,60 @@ +# +# requires: unix utilities +# GNU gettext +# + +DCC = dcc32.exe +RC = brcc32.exe + +SRC = delphi.pas gnugettext.pas gnugettextD4.pas gnugettextD5.pas \ + gnugettextDx.pas common.pas utils.pas \ + about.pas filter.pas options.pas main.pas readme.pas select.pas + +FRM = about.dfm filter.dfm options.dfm main.dfm readme.dfm select.dfm + +LANG = \ + locale\de\LC_MESSAGES\delphi.mo \ + locale\de\LC_MESSAGES\default.mo \ + locale\de\LC_MESSAGES\gpsbabel.mo \ + locale\es\LC_MESSAGES\delphi.mo \ + locale\es\LC_MESSAGES\default.mo \ + locale\es\LC_MESSAGES\gpsbabel.mo \ + locale\fr\LC_MESSAGES\delphi.mo \ + locale\fr\LC_MESSAGES\default.mo \ + locale\fr\LC_MESSAGES\gpsbabel.mo + +.suffixes: .po + +.po.mo: + msgfmt -o $@ $< + +.rc.res: + $(RC) $< + +.dpr.exe: + $(DCC) $< + +default: GPSBabelGUI.exe + +GPSBabelGUI.exe: GPSBabelGUI.dpr GPSBabelGUI.res $(SRC) $(FRM) $(LANG) + $(DCC) GPSBabelGUI.dpr + assemble GPSBabelGUI.exe --dxgettext + +run: GPSBabelGUI.exe + xcopy /Y ..\..\gpsbabel.exe + xcopy /Y ..\..\mingw\libexpat.dll + xcopy /Y ..\..\gpsbabel.html + GPSBabelGUI.exe + +GPSBabelGUI.res: GPSBabelGUI.dof dof2rc.exe + dof2rc GPSBabelGUI + $(RC) GPSBabelGUI.rc + +clean: + rm -f *.bak *.dcu *.exe *.mo *.dll *.res *.rc + rm -f *.~* *.??~ + rm -f readme.html README readme.xml + rm -f locale\de\LC_MESSAGES\*.mo + rm -f locale\es\LC_MESSAGES\*.mo + rm -f locale\fr\LC_MESSAGES\*.mo + diff --git a/win32/gui-2/README.gui b/win32/gui-2/README.gui new file mode 100644 index 000000000..220ac043f --- /dev/null +++ b/win32/gui-2/README.gui @@ -0,0 +1,70 @@ +* Adding your own language to GPSBabelGUI * +------------------------------------------- + +In first step you need an editor for .PO files. These files contains the +strings needed to be translated. The basic .po file for GPSBabelGUI is +default.po and should be located in your gui directory. The translation can be +done with any editor, but I suggest poedit (http://www.poedit.org/download.php). +poedit is the "must have" tool for doing such translations. + +If you have done the translation of the billions of messages from +the gui have to do the following: + +- Download and install the package dxgettext from "http://dybdahl.dk/dxgettext" +- Create a new folder below your gui directory in form + \locale\\LC_MESSAGES +- Replace with the shortcut for your language. +- The file "languagecodes.txt" from dxgettext is a good reference for + finding the valid shortcut. +- (1) Move your new default.po to folder LC_MESSAGE below . +- (2) Right-mouse-click on the .po file ... and you should see a new command + in your context menu "compile to mo file" ... doit. +- Borland Delphi uses a lot of internal strings, but you don't have to + translate them. On + "http://svn.berlios.de/wsvn/dxgettext/trunk/translations/" you will find + a lot of Delphi internal translations. For our gui you should download + "delphi.po" for Delphi5 and for +- Repeat steps (1) and (2) for delphi.po +- Start the gui and be happy. + +- That's all, but please please please, send us a copy of your translation. + A mail to gpsbabel-misc@lists.sourceforge.net with your translated + default.po will be implemented in the project (as fast as possible) and + will be available for many other users. + + +* Getting the source * +---------------------- + +There are two ways to get the source of the gui. One of them is source +release package you can download from SourceForge. Open "www.gpsbabel.org" +in your browser and go over "downloads" to the download list. The file you +need is called gpsbabel--.tar.gz. The gui source you will +find in the win32/gui-2 folder. + +The second way is to checkout the current development tree with CVS. +At SourceForge.net you will find the infos for working with cvs. +("http://sourceforge.net/cvs/?group_id=58972" for a short visit) + +To checkout the gpsbabel source tree the command line should look like this: + +cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/gpsbabel co gpsbabel + +This command will create a new folder in your working directory and +receive the complete source tree like the source tree but with all +changes made after the latest release. + +I generally encourage developers to work with the CVS tree instead of +the snapshots. + + +* Compiling from source * +------------------------- + +Currently the gui is developed under Delphi 4. Other releases of Delphi are +tested but are not used because of backward compatibility. If you want to help +us and Delphi is not in your software collection, "Delphi 6 Personal Edition" +would be the cheapest (or free) way. + + + diff --git a/win32/gui-2/about.dfm b/win32/gui-2/about.dfm new file mode 100644 index 0000000000000000000000000000000000000000..3437553e2abe7e2e824e2abec44decce73ae2e8a GIT binary patch literal 3505 zcmcgv&2QsG6rVUv>?BRL6#|LdAnjpST7_K@tPmVFNt12Vw2o>o%L*hIJCnr3nThO4 z)8#^L>H!ndMnVsXq zMpJ)eqPsg^R}nJ%ox3G-=uI0Ip9?J+Z1w0+%{@RB3W=Ks`e|b*ZXZ{+>fz zK2lp`CLGR+g^+o>(HBL88o648&Hff(m+Duotzxu=$Fw<%bM*mS$YnW(qM z#Pg|8Z|t=@jYmE6Olh%tXkddd z9~;zjh7o^gaRrqR=+nMOPaL`^)pU2z@+c8hmp*A)pZktPtb9_Imc}+#QPJ!ZMqO>jqL75qRges> zf(l81igD!b=L!wi88KBOZnVDKq$kwX=U|jtv`&sVqnb&q(0&Dh`0kX9=(aN*HHk&t zuFYAbLJL*wL@E>!dP{EY^2<6~|@eY#L&!FWM z_`L-;hWi2BIkW{&gqARO^|gdam{~5PA9%tL?j?Hm>={f1;THvg9Kj7A`AR;nxK`1% zjHk4iUZpfzEmun|OCv2yuU1GhCF_wK!Gagja%pz`3K%xzUDO8*@=D|d=io^Y{Qe^P zd31gEqIuvy3xcyO|5Q(zsc??a=l|s`bx2)7@YBXEYbq_-5DcPvdOcfD`CoEL$-b6T8&LP$^D9L%k=R)v z6R2*LOpYZQq8R*C0J5s|~U z#l#M!nnLn@bL{wd=JAn7rdSS%ComskF{b!o-w1(1&VNd6aR-mNFX#Zvx{no>T2! z*RdyRIW#;RZ)|!ke81lDWCtp))#9_KVFG1Bro4HrJ$P60dNTR&t=4V)#@)Mb-GRs3 zSa-<~AGp+E_!h5Q^@$ul$cE^48f!55kbAVthCFLQ67QqS@!svgL5-)tgdO0*M5MwX zg^fx_yEHT1u1WF^|juyxVO|7ce$rXh%MY}px9 zeX&P<+jGMHDI3~yytzN71-4rXyMZa>ld1_4;lp3R&AKKxI=7N<`No`0C`(JVZUP<* zJxEjv`!?j>8XRmsof3HII*cYr67NCHb{n>EPH5B@ZbYeSjQOHr+tihP&Ni7 zU-TTCGM{Gr&uh6$*?naIuJ7SJbH59Xq24hcH;&u*u<-=zN4+Pw*~YzYt9@j&_i*R9 z-Nt$c%ii;0`)VhzpKt%TUEPRhHtW{G%t7yB_8ea{`6&R%X#$lO;PtDdy<7wKdn&Y! zhTt>pYCmi3Q<)2NU{Dv%2CdeG+<;TWjoQ;vxhv>2Zf$FY=r6&JYv~I{y*-aCI?xFZ z)`miNsG7~W5S-O4!H(#nN7!f%{c5=F`3MK{-zSECixMQ*O_TKH#$e#E5hj??1$JZp zwT^u1QVO;&ZR!e9SGFkYbG^yIrfHOW;W3hj#`{7quH0O=;?erG(wy|m5%6cG0J`*p q$enK@SSv=76gzR|)wE)ho #0) do + begin + if ((str^ < '0') or (str^ > '9')) then Break; + Result := (Result * 10) + (Ord(str^) - Ord('0')); + str := str + 1; + end; +end; + +function GetFileVersion(const Filename: string): string; +var + buff: PChar; + hdl: DWORD; + len: DWORD; + sub: PChar; + sublen: UINT; + fix: PVSFixedFileInfo; + i: Integer; +begin + Result := '?.?'; + + FillChar(CFixedFileinfo, SizeOf(CFixedFileinfo), #0); + + len := GetFileVersionInfoSize(PChar(Filename), hdl); + if not(len > 0) then exit; + + GetMem(buff, len); + try + + if not GetFileVersionInfo(PChar(FileName), 0, len, buff) then Exit; + + fix := Pointer(buff); + i := len - SizeOf(fix^); + while (i > 0) do + begin + Dec(i); + if (fix.dwSignature = $feef04bd) then + begin + CFixedFileinfo := fix^; + Break; + end; + PChar(fix) := PChar(fix) + 1; + end; + + if not VerQueryValue(buff, PChar('\\StringFileInfo\\040904E4\\FileVersion'), + Pointer(sub), sublen) then Exit; + if not(sublen > 0) then Exit; + Result := string(sub); + finally + FreeMem(buff); + end; +end; + +{ TOptions } + +constructor TOptions.Create(ACapabilities: TCapabilities); +begin + inherited Create; + FCaps := ACapabilities; + Sorted := False; +end; + +procedure TOptions.AddOptionLine(const ALine: string); +var + buff: array[0..1023] of Char; + cin, cend: PChar; + index: Integer; + opt: POption; + list: TStringList; + i: Integer; + s: string; +begin + StrPCopy(buff, ALine); + StrCat(buff, #9); + + cin := @buff; + index := 0; + while (true) do + begin + cend := StrScan(cin, #9); + if (cend = nil) then break; + cend^ := #0; + + case index of + 0: + if (StrIComp(cin, 'option') <> 0) then + Exit else + begin + New(opt); + FillChar(opt^, SizeOf(opt^), #0); + end; + 1: + opt.format := string(cin); + 2: + opt.name := string(cin); + 3: + opt.hint := string(cin); + 4: + for i := 0 to high(OTypes) do + if (StrIComp(cin, OTypes[i]) = 0) then + begin + opt.otype := i; + Break; + end; + 5: + if (cin^ <> #0) then + begin + opt.gbdef := StrNew(cin); + if (opt.def = nil) then + opt.def := opt.gbdef; + end; + 6: + if (cin^ <> #0) then + opt.min := StrNew(cin); + 7: + if (cin^ <> #0) then + opt.max := StrNew(cin); + end; + + index := index + 1; + cin := cend + 1; + end; + + if (opt.name = 'snlen') and (opt.gbdef = nil) then + begin + opt.gbdef := StrNew('10'); + opt.def := opt.gbdef; + end; + + index := Self.IndexOf(opt.format); + if (index >= 0) then + list := TStringList(Self.Objects[index]) + else begin + list := TStringList.Create; + list.Sorted := True; + Self.AddObject(opt.format, list); + end; + list.AddObject(opt.name, Pointer(opt)); +end; + +procedure TOptions.DebugGetHints(List: TStringList); +var + i, j, k: Integer; + l: TStrings; + o: POption; +begin + List.Clear; + List.Sorted := True; + for i := 0 to Count - 1 do + begin + l := Pointer(Objects[i]); + for j := 0 to l.Count - 1 do + begin + o := Pointer(l.Objects[j]); + k := List.IndexOf(o.hint); + if (k < 0) then + List.Add(o.hint); + end; + end; +end; + +function TOptions.FormatOpts(const Descr: string): TStringList; +var + i: Integer; + s: string; +begin + s := FCaps.GetName(Descr); + if (s <> '') and Self.Find(s, i) then + Result := TStringList(Self.Objects[i]) + else + Result := nil; +end; + +function TOptions.GetList: TStrings; +begin + Result := Self; +end; + +function TOptions.HasFormatOpts(const Format: string): Boolean; +begin + Result := (FormatOpts(Format) <> nil); +end; + +procedure TOptions.SetList(const Value: TStrings); +var + i: Integer; +begin + Clear; + for i := 0 to Value.Count - 1 do + AddOptionLine(Value[i]); + Sorted := True; +end; + +{ TCapabilities } + +procedure TCapabilities.AddFormat(const Line: string); +var + index: Integer; + buff: array[0..1023] of Char; + cin, cend: PChar; + i: Integer; + scaps: string; + ext: string; + comment: string; + name: string; + internal: string; + caps: Integer; + info: PFileInfo; + +begin + StrPCopy(buff, Line); + StrCat(buff, #9); + + cin := @buff; + index := 0; + + while (true) do + begin + cend := StrScan(cin, #9); + if (cend = nil) then break; + cend^ := #0; + + case index of + 0: + if (StrIComp(cin, 'option') = 0) then + Exit + else + internal := StrPas(cin); + 1: + scaps := StrPas(cin); + 2: + name := StrPas(cin); + 3: + ext := StrPas(cin); + else + begin + comment := StrPas(cin); + if (Length(comment) = 0) or (Length(name) = 0) then break; + +// if (comment[1] = '?') then break; + + caps := 0; + for i := 1 to Length(scaps) do + if (scaps[i] <> '-') then caps := caps or (1 shl (i - 1)); + + New(info); + info.Descr := comment; + info.Ext := ext; + info.internal := internal; + info.Capas := caps; + + i := SELF.Add(name); + SELF.PutObject(i, Pointer(info)); + + if (name = 'garmin_txt') then + begin + gpsbabel_knows_inifile := True; + // add -p "" to command-line + end; + break; + end; + end; + + index := index + 1; + cin := cend + 1; + end; +end; + +function TCapabilities.CanReadAny(Index: Integer): Boolean; +var + caps: Integer; +begin + caps := PFileInfo(SELF.Objects[Index]).Capas; + Result := caps and (1 or 4 or 16) <> 0; +end; + +function TCapabilities.CanWriteAny(Index: Integer): Boolean; +var + caps: Integer; +begin + caps := PFileInfo(SELF.Objects[Index]).Capas; + Result := caps and (2 or 8 or 32) <> 0; +end; + +function TCapabilities.GetCaps(const Descr: string): Integer; +var + info: PFileInfo; + i: Integer; +begin + for i := 0 to Count - 1 do + begin + info := PFileInfo(Objects[i]); + if (AnsiCompareText(info.Descr, Descr) = 0) then + begin + Result := info.Capas; + Exit; + end; + end; + Result := 0; +end; + +function TCapabilities.GetDescr(Index: Integer): string; +var + info: PFileInfo; +begin + info := PFileInfo(Objects[Index]); + Result := info.Descr; +end; + +function TCapabilities.GetExt(const Descr: string): string; +var + i: Integer; + info: PFileInfo; +begin + for i := 0 to Count - 1 do + begin + info := PFileInfo(Objects[i]); + if (AnsiCompareText(info.Descr, Descr) = 0) then + begin + Result := info.Ext; + Exit; + end; + end; + Result := '.*'; +end; + +function TCapabilities.GetList: TStrings; +begin + Result := TStringList.Create; +end; + +function TCapabilities.GetName(const Descr: string): string; +var + i: Integer; + info: PFileInfo; +begin + for i := 0 to Count - 1 do + begin + info := PFileInfo(Objects[i]); + if (AnsiCompareText(info.Descr, Descr) = 0) then + begin + Result := SELF[i]; + Exit; + end; + end; + Result := 'unknown'; +end; + +function TCapabilities.IsDevice(Index: Integer): Boolean; +var + info: PFileInfo; +begin + info := PFileInfo(Objects[Index]); + Result := (AnsiCompareText(info.Internal, 'serial') = 0); +end; + +function TCapabilities.IsFile(Index: Integer): Boolean; +var + info: PFileInfo; + name: string; +begin + info := PFileInfo(Objects[Index]); + Result := (AnsiCompareText(info.Internal, 'file') = 0); +end; + +procedure TCapabilities.SetList(const Value: TStrings); +var + i: Integer; + s: string; +begin + Clear; + for i := 0 to Value.Count - 1 do + begin + s := Value.Strings[i]; + AddFormat(s); + end; +end; + +(* +function Open_gpsbabel_ini(): TInifile; +var + s: string; +begin + s := SysUtils.ExpandFileName(SGPSBabelIniFilename); + if not(SysUtils.FileExists(s)) then + s := SysUtils.ExtractFilePath(ParamStr(0)) + SGPSBabelIniFilename; + if not(SysUtils.FileExists(s)) then + Result := TIniFile.Create(SGPSBabelIniFilename) + else + Result := TIniFile.Create(s) +end; +*) + +initialization + + gpsbabel_exe := SysUtils.ExtractFilePath(ParamStr(0)) + SGPSBabelExeFilename; + SGPSBabelGUIVersion := GetFileVersion(ParamStr(0)); +//gpsbabel_ini := Open_gpsbabel_ini(); + +end. diff --git a/win32/gui-2/default.po b/win32/gui-2/default.po new file mode 100644 index 000000000..1151194a9 --- /dev/null +++ b/win32/gui-2/default.po @@ -0,0 +1,833 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2005-12-06 17:57\n" +"PO-Revision-Date: 2005-12-06 17:57\n" +"Last-Translator: Somebody \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted " +"on" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for gpsbabel command line " +"program" +msgstr "" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF " +"CHARGE" +msgstr "" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "" + +#. frmFilter..gbTracks..Caption +#: filter.dfm:31 +#. frmMain..pnBottom..cbTracks..Caption +#: main.dfm:589 +msgid "&Tracks" +msgstr "" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +msgid "by" +msgstr "" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "" + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "" + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "" + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of " +"trackpoint" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "" + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "" + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate " +"timestamps)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:308 +msgid "&Routes && Tracks" +msgstr "" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:316 +msgid "limit to" +msgstr "" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:324 +msgid "Points" +msgstr "" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:331 +msgid "Simplify routes and tracks by limited number of " +"points" +msgstr "" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:332 +msgid "Simplify" +msgstr "" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:341 +msgid "Upper limit of points for routes and " +"tracks" +msgstr "" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:363 +msgid "Reverse routes and tracks" +msgstr "" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:364 +msgid "Reverse" +msgstr "" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:381 +msgid "OK" +msgstr "" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:417 +msgid "File based filters" +msgstr "" + +#. frmFilter..gbWaypoints..Caption +#: filter.dfm:437 +#. frmMain..pnBottom..cbWaypoints..Caption +#: main.dfm:563 +msgid "&Waypoints" +msgstr "" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:446 +msgid "Latitude" +msgstr "" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:454 +msgid "Longitude" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:462 +msgid "Merge waypoints with duplicate locations" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:463 +msgid "locations" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:472 +msgid "Merge waypoints with duplicate \"short " +"name\"" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:473 +msgid "\"short names\"" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:482 +msgid "Merge waypoints separated by less then" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:483 +msgid "Position" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:511 +msgid "Sort waypoints by \"short name\" or by " +"description" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:512 +msgid "Sort" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:520 +msgid "Merge duplicate waypoints" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:521 +msgid "Duplicates" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:530 +msgid "Include points based on their proximity to central " +"point" +msgstr "" + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:531 +msgid "Radius" +msgstr "" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:559 +msgid "Latitude of central point" +msgstr "" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:569 +msgid "Longitude of central point" +msgstr "" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:269 +#: main.pas:274 +#: main.pas:460 +#: main.pas:842 +msgid "Input" +msgstr "" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#: main.dfm:68 +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#: main.dfm:233 +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#: main.dfm:1428 +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#: main.dfm:1433 +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:1447 +msgid "Options" +msgstr "" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#: main.dfm:76 +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:263 +msgid "Format" +msgstr "" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#: main.dfm:83 +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#: main.dfm:270 +#. frmMain..ActionList1..acFileExit..Category +#: main.dfm:1409 +#. frmMain..ActionList1..acFileClearMemo..Category +#: main.dfm:1438 +#. frmMain..ActionList1..acFileOutputToScreen..Category +#: main.dfm:1453 +#. frmMain..ActionList1..acFileChangeLanguage..Category +#: main.dfm:1465 +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:1470 +#: main.pas:839 +#: main.pas:893 +msgid "File" +msgstr "" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#: main.dfm:115 +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:303 +msgid "Device" +msgstr "" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:152 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:367 +msgid "- default -" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:198 +msgid "Format for input from device" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:212 +msgid "Format for input from file" +msgstr "" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:226 +#: main.pas:270 +#: main.pas:275 +#: main.pas:469 +#: main.pas:896 +msgid "Output" +msgstr "" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:277 +msgid "Start the file save dialog" +msgstr "" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:300 +msgid "Write data to device instead to file" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:313 +msgid "Format for ouput to device" +msgstr "" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:325 +msgid "Options for the selected output format" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:336 +msgid "Format for output to file" +msgstr "" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:349 +msgid "Write data to given filename" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:361 +msgid "Characterset for output data" +msgstr "" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:394 +msgid "Write data to device ..." +msgstr "" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:423 +msgid "What ?" +msgstr "" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:562 +msgid "Process waypoint information" +msgstr "" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:576 +msgid "Process route information" +msgstr "" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:577 +msgid "&Routes" +msgstr "" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:588 +msgid "Process track information" +msgstr "" + +#. frmMain..pnBottom..btnFilter..Caption +#: main.dfm:602 +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:1403 +msgid "&Filter" +msgstr "" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:646 +msgid "Start data conversion" +msgstr "" + +#. frmMain..pnBottom..btnProcess..Caption +#: main.dfm:649 +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:1396 +msgid "let's go" +msgstr "" + +#. frmMain..OpenDialog..Filter +#: main.dfm:711 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "" + +#. frmMain..SaveDialog..Filter +#: main.dfm:717 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "" + +#. frmMain..ActionList1..acConvert..Category +#: main.dfm:1395 +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1402 +msgid "Babel" +msgstr "" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1404 +msgid "Filter incomming data before writing them to file or " +"device" +msgstr "" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1410 +msgid "E&xit" +msgstr "" + +#. frmMain..ActionList1..acHelpAbout..Category +#: main.dfm:1414 +#. frmMain..ActionList1..acHelpIntro..Category +#: main.dfm:1419 +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1423 +msgid "Help" +msgstr "" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1415 +msgid "&About" +msgstr "" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1420 +msgid "&Intro" +msgstr "" + +#. frmMain..ActionList1..acHelpReadme..Caption +#: main.dfm:1424 +#. frmReadme..Caption +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1429 +msgid "... for source format" +msgstr "" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1434 +msgid "... for target format" +msgstr "" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1439 +msgid "Clear output" +msgstr "" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1440 +msgid "Clear messages" +msgstr "" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1448 +msgid "Enable characterset transformation" +msgstr "" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1454 +msgid "Output to screen" +msgstr "" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1466 +msgid "Change language" +msgstr "" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1471 +msgid "Export gpsbabel.csv (unicode)" +msgstr "" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1479 +msgid "&File" +msgstr "" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1487 +msgid "Export" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1508 +msgid "&Options" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1510 +msgid "Synthesize shortnames" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1513 +msgid "Ignore shortnames from source data and synthesize them from " +"description or notes" +msgstr "" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1517 +msgid "Force selected GPS data types (nuketypes " +"filter)" +msgstr "" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1558 +msgid "&Help" +msgstr "" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "" + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "" + +#: about.pas:87 +msgid "German by Olaf Klein" +msgstr "" + +#: about.pas:88 +msgid "French by Lilian Morinon" +msgstr "" + +#: about.pas:131 +msgid "Please have a look at the file README.GUI.\n" +"\nThere you will find all information you need to\n" +"get GPSBabelGUI working in your own " +"language." +msgstr "" + +#: filter.pas:199 +msgid "Feet" +msgstr "" + +#: filter.pas:200 +msgid "Meter" +msgstr "" + +#: filter.pas:203 +msgid "Miles" +msgstr "" + +#: filter.pas:204 +msgid "Kilometer" +msgstr "" + +#: filter.pas:214 +msgid "Not supported by gpsbabel.exe, release " +"%s!" +msgstr "" + +#: filter.pas:250 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "" + +#: filter.pas:530 +#: options.pas:654 +msgid "Discard changes?" +msgstr "" + +#: main.pas:243 +msgid "Internal development release" +msgstr "" + +#: main.pas:245 +msgid "BETA" +msgstr "" + +#: main.pas:247 +msgid "Private release" +msgstr "" + +#: main.pas:249 +msgid "Special release" +msgstr "" + +#: main.pas:340 +msgid "The file \"gpsbabel.exe\" found in current directory is too " +"old!" +msgstr "" + +#: main.pas:409 +#: main.pas:543 +msgid "All files|*.*" +msgstr "" + +#: main.pas:477 +msgid "Select and edit options for \"%s\"" +msgstr "" + +#: main.pas:481 +msgid "No options available for \"%s\"" +msgstr "" + +#: main.pas:590 +msgid "File %s not found." +msgstr "" + +#: main.pas:648 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "" + +#: main.pas:649 +msgid "Warning" +msgstr "" + +#: main.pas:682 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "" + +#: main.pas:691 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "" + +#: main.pas:693 +msgid "Converted successfully from \"%s\" to " +"\"%s\"." +msgstr "" + +#: main.pas:794 +msgid "GPSBabel, version %s" +msgstr "" + +#: main.pas:828 +#: main.pas:883 +msgid "Port" +msgstr "" + +#: main.pas:980 +msgid "Options for \"%s\"" +msgstr "" + +#: main.pas:1169 +#: main.pas:1239 +msgid "Choose language" +msgstr "" + +#: main.pas:1169 +msgid "for GUIBabelGUI" +msgstr "" + +#: main.pas:1239 +msgid "for export" +msgstr "" + +#. override; +#: options.pas:143 +msgid "Be aware, that most options are made for the output side. " +msgstr "" + +#: options.pas:144 +msgid "Currently we don't have a flag which tells us which direction is used " +"by the options." +msgstr "" + +#: options.pas:204 +msgid "Short \"%s\"" +msgstr "" + +#: options.pas:325 +msgid "Invalid line format!" +msgstr "" + +#: options.pas:346 +msgid "Unknown option \"%s\"!" +msgstr "" + +#: utils.pas:113 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "" + +#: utils.pas:118 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "" + +#. dwCreationFlags, // creation flags +#: utils.pas:137 +msgid "Could not run \"gpsbabel.exe\" (Error " +"%d)!" +msgstr "" + +#: utils.pas:165 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "" + diff --git a/win32/gui-2/delphi.pas b/win32/gui-2/delphi.pas new file mode 100644 index 000000000..c9c5261c5 --- /dev/null +++ b/win32/gui-2/delphi.pas @@ -0,0 +1,93 @@ +unit delphi; + +// Delpi compatibility unit // + +interface + +uses + SysUtils, TypInfo; + +{$IFDEF VER120} +function GetPropInfo(Instance: TObject; const PropertyName: string): PPropInfo; overload; +function GetPropInfo(Instance: TObject; const Name: string; var PropInfo: TPropInfo): Boolean; overload; +function GetObjectProp(Instance: TObject; Info: PPropInfo): TObject; +function GetStrProp(Instance: TObject; const Name: string): string; overload; +function GetStrProp(Instance: TObject; Info: PPropInfo): string; overload; +procedure SetStrProp(Instance: TObject; const Name, Value: string); overload; +procedure SetStrProp(Instance: TObject; Info: PPropInfo; const Value: string); overload; +{$ENDIF} + +implementation + +{$IFDEF VER120} +function GetPropInfo(Instance: TObject; const PropertyName: string): PPropInfo; +begin + Result := TypInfo.GetPropInfo(Instance.ClassInfo, PropertyName); +end; + +function GetObjectProp(Instance: TObject; Info: PPropInfo): TObject; +begin + Result := Pointer(TypInfo.GetOrdProp(Instance, Info)); +end; + +function GetPropInfo(Instance: TObject; const Name: string; var PropInfo: TPropInfo): Boolean; +var + Props: PPropList; + TypeData: PTypeData; + Info: PPropInfo; + i: Integer; +begin + TypeData := GetTypeData(Instance.ClassInfo); + if ((TypeData <> nil) and (TypeData.PropCount > 0)) then + begin + GetMem(Props, TypeData.PropCount * SizeOf(Pointer)); + try + GetPropInfos(Instance.ClassInfo, Props); + for i := 0 to TypeData.PropCount - 1 do + begin + Info := Props[i]; + if (CompareText(Info.Name, Name) = 0) then + begin + PropInfo := Info^; + Result := True; + Exit; + end + end; + finally + FreeMem(Props); + end; + end; + Result := False; +end; + +function GetStrProp(Instance: TObject; Info: PPropInfo): string; +begin + Result := TypInfo.GetStrProp(Instance, Info); +end; + +function GetStrProp(Instance: TObject; const Name: string): string; +var + Info: TPropInfo; +begin + if GetPropInfo(Instance, Name, Info) then + Result := TypInfo.GetStrProp(Instance, @Info) + else + Result := ''; +end; + +procedure SetStrProp(Instance: TObject; const Name, Value: string); +var + Info: TPropInfo; +begin + if GetPropInfo(Instance, Name, Info) then + SetStrProp(Instance, @Info, Value); +end; + +procedure SetStrProp(Instance: TObject; Info: PPropInfo; const Value: string); +begin + TypInfo.SetStrProp(Instance, Info, Value); +end; + +{$ENDIF} + +end. diff --git a/win32/gui-2/dof2rc.dpr b/win32/gui-2/dof2rc.dpr new file mode 100644 index 000000000..feb557c21 --- /dev/null +++ b/win32/gui-2/dof2rc.dpr @@ -0,0 +1,108 @@ +program DOF2RC; +uses + Windows, SysUtils, Inifiles; + +var + Ini: TInifile; + IFName: string; + OFName: string; + OFile: Text; + s: string; + i: Integer; + + procedure WriteValue(const Key: string); + var + s: string; + begin + s := Ini.ReadString('Version Info Keys', Key, ''); + WriteLn(OFile, #9#9'VALUE "', Key, '", "', s, '\0"'); + end; + +begin + IFName := ChangeFileExt(ExpandFileName(ParamStr(1)), '.dof'); + Ini := TIniFile.Create(IFName); + try + OFName := SysUtils.ChangeFileExt(Ini.FileName, '.rc'); + if not Ini.SectionExists('Compiler') then + begin + WriteLn('Invalid DOF!'); + Halt(1); + end; + + System.Assign(OFile, OFName); +{$I-} + System.Rewrite(OFile); +{$I+} + if (IOResult <> 0) then + begin + Halt(1); + end; + try + s := SysUtils.ExtractFileName(Ini.FileName); + s := SysUtils.ChangeFileExt(s, '.ico'); + + System.WriteLn(OFile, 'MAINICON ICON "', s, '"'); + System.WriteLn(OFile); + + if not Ini.SectionExists('Version Info') then Exit; + + WriteLn(OFile, '1 VERSIONINFO'); + s := Ini.ReadString('Version Info', 'MajorVer', '0') + ',' + + Ini.ReadString('Version Info', 'MinorVer', '0') + ',' + + Ini.ReadString('Version Info', 'Release', '0') + ',' + + Ini.ReadString('Version Info', 'Build', '0'); + WriteLn(OFile, 'FILEVERSION ', s); + WriteLn(OFile, 'PRODUCTVERSION ', s); + WriteLn(OFile, 'FILEOS 0x4'); + WriteLn(OFile, 'FILETYPE 0x1'); + WriteLn(OFile, 'FILESUBTYPE 0x0L'); + WriteLn(OFile, 'FILEFLAGSMASK 0x3fL'); + + i := 0; + if (Ini.ReadInteger('Version Info', 'Debug', 0) <> 0) then i := 1; + if (Ini.ReadInteger('Version Info', 'PreRelease', 0) <> 0) then i := (i or 2); + if (Ini.ReadInteger('Version Info', 'Special', 0) <> 0) then i := (i or $20); + if (Ini.ReadInteger('Version Info', 'Private', 0) <> 0) then i := (i or 8); + if (i <> 0) then + WriteLn(OFile, 'FILEFLAGS ', SysUtils.Format('0x%2.2x', [i])); + + WriteLn(OFile, '{'); + WriteLn(OFile, 'BLOCK "StringFileInfo"'); + WriteLn(OFile, '{'); + + if ini.SectionExists('Version Info Keys') then + begin + WriteLn(OFile, #9'BLOCK "040904E4"'); + WriteLn(OFile, #9'{'); + WriteValue('CompanyName'); + WriteValue('FileDescription'); + WriteValue('FileVersion'); + WriteValue('InternalName'); + WriteValue('LegalCopyright'); + WriteValue('LegalTrademarks'); + WriteValue('OriginalFilename'); + WriteValue('ProductName'); + WriteValue('ProductVersion'); + WriteValue('Comments'); + WriteLn(OFile, #9'}'); + end; + WriteLn(OFile, '}'); + + WriteLn(OFile, 'BLOCK "VarFileInfo"'); + WriteLn(OFile, '{'); + WriteLn(OFile, #9'VALUE "Translation", ', + SysUtils.Format('0x%4.4x 0x%4.4x', [ + Ini.ReadInteger('Version Info', 'Locale', 1033), + Ini.ReadInteger('Version Info', 'CodePage', 1252)])); + WriteLn(OFile, '}'); + WriteLn(OFile, '}'); + + + finally + System.Close(OFile); + end; + finally + ini.Free; + end; +end. + diff --git a/win32/gui-2/filter.dfm b/win32/gui-2/filter.dfm new file mode 100644 index 0000000000000000000000000000000000000000..53766bae63bb5b12b1e91b62dcf0465a08a2644f GIT binary patch literal 8761 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 O#SAV`{K1B*Y5xKcuAsI6 literal 0 HcmV?d00001 diff --git a/win32/gui-2/filter.pas b/win32/gui-2/filter.pas new file mode 100644 index 000000000..9b5b07614 --- /dev/null +++ b/win32/gui-2/filter.pas @@ -0,0 +1,733 @@ +unit filter; + +{ + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +interface + +uses + gnugettext, gnugettextDx, + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ComCtrls, Buttons, Mask, ExtCtrls, Registry, + common, utils; + +type + TfrmFilter = class(TForm) + gbTracks: TGroupBox; + cbTrackTitle: TCheckBox; + edTrackTitleValue: TEdit; + cbTrackSplit: TCheckBox; + cbTrackTime: TCheckBox; + udTimeHours: TUpDown; + edTrackTimeHours: TEdit; + udTimeMinutes: TUpDown; + edTrackTimeMinutes: TEdit; + edTrackTimeDays: TEdit; + udTimeDays: TUpDown; + edTrackTimeSeconds: TEdit; + udTimeSeconds: TUpDown; + lbTimePlusMinus: TLabel; + lbTimeDays: TLabel; + lbTimeHours: TLabel; + lbTimeMinutes: TLabel; + lbTimeSeconds: TLabel; + cbTrackStart: TCheckBox; + dtpTrackStartDate: TDateTimePicker; + dtpTrackStartTime: TDateTimePicker; + cbTrackStop: TCheckBox; + dtpTrackStopDate: TDateTimePicker; + dtpTrackStopTime: TDateTimePicker; + gbRoutes: TGroupBox; + cbRouteSimplify: TCheckBox; + lbRouteSimplifyCount: TLabel; + edRoutesSimplifyMaxPoints: TMaskEdit; + udRouteSompifyMaxPoints: TUpDown; + lbRouteSimplifyText: TLabel; + pnBottom: TPanel; + btnOK: TBitBtn; + gbWaypoints: TGroupBox; + cbWayptMergeDupLoc: TCheckBox; + cbReverse: TCheckBox; + cbWayptMergeDupNames: TCheckBox; + cbWayptMergeDistance: TCheckBox; + cobWayptMergeDist: TComboBox; + edWayptMergeDist: TEdit; + cbWayptSort: TCheckBox; + cbWayptMergeDups: TCheckBox; + btnCancel: TBitBtn; + cbTrackPack: TCheckBox; + cbTrackMerge: TCheckBox; + BitBtn1: TBitBtn; + cbWayptRadius: TCheckBox; + edWayptRadius: TEdit; + cobWayptRadius: TComboBox; + lbWayptRadiusLat: TLabel; + lbWayptRadiusLon: TLabel; + edWayptRadiusLat: TEdit; + edWayptRadiusLon: TEdit; + cbTrackRangeTimeZone: TCheckBox; + btnHelp: TBitBtn; + cbTrackFixes: TCheckBox; + cbTrackCourse: TCheckBox; + cbTrackSpeed: TCheckBox; + gbTransform: TGroupBox; + cobTransform: TComboBox; + cbTransform: TCheckBox; + cbTransformDelete: TCheckBox; + procedure cbTrackTimeClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure cbTrackTitleClick(Sender: TObject); + procedure btnOKClick(Sender: TObject); + procedure cbTrackStartClick(Sender: TObject); + procedure cbTrackStopClick(Sender: TObject); + procedure cbRouteSimplifyClick(Sender: TObject); + procedure cbTrackPackClick(Sender: TObject); + procedure cbTrackMergeClick(Sender: TObject); + procedure cbWayptMergeDistanceClick(Sender: TObject); + procedure cbWayptMergeDupsClick(Sender: TObject); + procedure cbWayptRadiusClick(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure FormShow(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure btnHelpClick(Sender: TObject); + procedure cbTransformClick(Sender: TObject); + private + { Private-Deklarationen } + lTrackTimeList: TList; + FTracksEnabled: Boolean; + FInitialValues: string; + function AnyChecked(Control: TWinControl): Boolean; + procedure EnableList(List: TList; Enable: Boolean = True); + procedure SetTracksEnabled(const Value: Boolean); + function AllValid: Boolean; + function ValidateNumerical(AEdit: TCustomEdit; AMin, AMax: Extended): Boolean; + procedure ChangeCheckBoxesChecked(AComponent: TComponent; Restore: Boolean = False); + procedure LoadSettingsFromInifile(); + procedure LoadSettingsFromRegistry(); + procedure StoreSettingsToInifile(); + procedure StoreSettingsToRegistry(); + public + { Public-Deklarationen } + function CmdLine: string; + property TracksEnabled: Boolean read FTracksEnabled write SetTracksEnabled; + end; + +type + eOutOfRange = class(Exception); + +var + frmFilter: TfrmFilter = nil; + +implementation + +{$R *.DFM} + +procedure FixPosition(AControl, LeftFromMe: TControl; IsText: Boolean); +begin + AControl.Left := LeftFromMe.Left + LeftFromMe.Width; + if (IsText) then + AControl.Left := AControl.Left + 4; +end; + +procedure EnableAll(Parent: TWinControl; Enable: Boolean); +var + i: Integer; + c: TComponent; + master: TComponent; + ctrl: TControl; +begin + if (Parent = nil) then Exit; + master := Parent.Owner; + if (master = nil) then Exit; + for i := 0 to master.ComponentCount - 1 do + begin + c := master.Components[i]; + if not(c.InheritsFrom(TControl)) then Continue; + ctrl := Pointer(c); + if not(ctrl.Parent = Parent) then Continue; + ctrl.Enabled := Enable; + end; +end; + +{ TfrmFilter } + +procedure TfrmFilter.FormCreate(Sender: TObject); +var + CurrentTime: TDateTime; + +begin + TranslateComponent(SELF); + + cobTransform.Items.Clear; + cobTransform.Items.Add(_('Waypoints') + ' -> ' + _('Routes')); + cobTransform.Items.Add(_('Routes') + ' -> ' + _('Waypoints')); + cobTransform.Items.Add(_('Routes') + ' -> ' + _('Tracks')); + cobTransform.Items.Add(_('Tracks') + ' -> ' + _('Routes')); + cobTransform.Items.Add(_('Waypoints') + ' -> ' + _('Tracks')); + cobTransform.Items.Add(_('Tracks') + ' -> ' + _('Waypoints')); + cobTransform.ItemIndex := 0; + + CurrentTime := SysUtils.Now; + dtpTrackStartDate.DateTime := Int(CurrentTime); + dtpTrackStopDate.DateTime := Int(CurrentTime); + + lTrackTimeList := TList.Create; + + lTrackTimeList.Add(edTrackTimeDays); + lTrackTimeList.Add(edTrackTimeHours); + lTrackTimeList.Add(edTrackTimeMinutes); + lTrackTimeList.Add(edTrackTimeSeconds); + + EnableList(lTrackTimeList, False); + + FixPosition(edTrackTimeDays, lbTimePlusMinus, True); + FixPosition(udTimeDays, edTrackTimeDays, False); + FixPosition(lbTimeDays, udTimeDays, True); + + FixPosition(edTrackTimeHours, lbTimeDays, True); + FixPosition(udTimeHours, edTrackTimeHours, False); + FixPosition(lbTimeHours, udTimeHours, True); + + FixPosition(edTrackTimeMinutes, lbTimeHours, True); + FixPosition(udTimeMinutes, edTrackTimeMinutes, False); + FixPosition(lbTimeMinutes, udTimeMinutes, True); + + FixPosition(edTrackTimeSeconds, lbTimeMinutes, True); + FixPosition(udTimeSeconds, edTrackTimeSeconds, False); + FixPosition(lbTimeSeconds, udTimeSeconds, True); + + FixPosition(lbWayptRadiusLat, cobWayptRadius, True); + FixPosition(edWayptRadiusLat, lbWayptRadiusLat, True); + FixPosition(lbWayptRadiusLon, edWayptRadiusLat, True); + FixPosition(edWayptRadiusLon, lbWayptRadiusLon, True); + + // will not be translated, fill by hand + + cobWayptMergeDist.Items.Add(_('Feet')); + cobWayptMergeDist.Items.Add(_('Meter')); + cobWayptMergeDist.ItemIndex := 0; + + cobWayptRadius.Items.Add(_('Miles')); + cobWayptRadius.Items.Add(_('Kilometer')); + cobWayptRadius.ItemIndex := 0; + + dtpTrackStopTime.Time := 1 - (1.0 / (24*60*60)); + + // Enable/Disable depending on gpsbabel.exe version + + if (common.gpsbabel_vfmt < '001.002.007') then + begin + EnableAll(gbTracks, False); + gbTracks.Hint := Format(_('Not supported by gpsbabel.exe, release %s!'), [ + gpsbabel_version]); + gbTracks.ShowHint := True; + end; + + if not(gpsbabel_knows_inifile) then + begin + cbTrackFixes.Enabled := False; + cbTrackCourse.Enabled := False; + cbTrackSpeed.Enabled := False; + end; + + LoadSettingsFromRegistry(); + + gbTransform.Enabled := (common.gpsbabel_vfmt >= '001.003.002'); + EnableAll(gbTransform, gbTransform.Enabled); +end; + +function TfrmFilter.ValidateNumerical(AEdit: TCustomEdit; AMin, AMax: Extended): Boolean; +var + s: string; + v: Extended; +begin + Result := True; + if not(AEdit.Enabled) then Exit; + if (ModalResult <> mrOK) then Exit; + + Result := False; + s := Trim(AEdit.Text); + if (s = '') then s := '0'; + while (Pos(',', s) <> 0) do + s[Pos(',', s)] := '.'; + + AEdit.Text := s; + + try + v := SysUtils.StrToFloat(s); + except + on E: EConvertError do + begin + AEdit.SetFocus; + raise; + end; + end; + + if (v < AMin) or (v > AMax) then + begin + AEdit.SetFocus; + raise eOutOfRange.CreateFmt(_('Value (%s) out of range (%g to %g)!'), + [s, AMin, AMax]); + end; + Result := True; +end; + +procedure TfrmFilter.cbTrackTimeClick(Sender: TObject); +begin + EnableList(lTrackTimeList, cbTrackTime.Checked); +end; + +procedure TfrmFilter.EnableList(List: TList; Enable: Boolean); +var + i: Integer; + o: TObject; +begin + for i := 0 to List.Count - 1 do + begin + o := Pointer(List.Items[i]); + if (o is TControl) then + with o as TControl do + Enabled := Enable; + end; +end; + +procedure TfrmFilter.cbTrackTitleClick(Sender: TObject); +begin + edTrackTitleValue.Enabled := cbTrackTitle.Checked; +end; + +function TfrmFilter.CmdLine: string; + + procedure SimpleOption(var CmdLine: string; CheckBox: TCheckBox; const Option: string); + begin + if (CheckBox.Checked) then + CmdLine := Format('%s -x %s', [CmdLine, Option]); + end; + +var + s: string; + tz_Info: TTimeZoneInformation; + dt: TDateTime; + dt_bias: TDateTime; +begin + Result := ''; + if not AnyChecked(Self) then Exit; + + Result := ''; + + if gbTransform.Enabled and cbTransform.Checked then + begin + Result := Format('%s -x %s', [Result, 'transform,']); + case cobTransform.ItemIndex of + 0: Result := Result + 'rte=wpt'; + 1: Result := Result + 'wpt=rte'; + 2: Result := Result + 'trk=rte'; + 3: Result := Result + 'rte=trk'; + 4: Result := Result + 'trk=wpt'; + 5: Result := Result + 'wpt=trk'; + end; + if cbTransformDelete.Checked then + Result := Result + ',del=y' else + Result := Result + ',del=n'; + end; + if AnyChecked(gbWaypoints) then + begin + if cbWayptMergeDups.Checked and + (cbWayptMergeDupNames.Checked or cbWayptMergeDupLoc.Checked) then + begin + Result := Format('%s -x %s', [Result, 'duplicate']); + if cbWayptMergeDupNames.Checked then + Result := Format('%s,%s', [Result, 'shortname']); + if cbWayptMergeDupLoc.Checked then + Result := Format('%s,%s', [Result, 'location']); + end; + if cbWayptMergeDistance.Checked then + begin + Result := Format('%s -x position,distance=%s', [Result, edWayptMergeDist.Text]); + if (cobWayptMergeDist.ItemIndex = 0) then + Result := Result + 'f' else + Result := Result + 'm'; + end; + if cbWayptRadius.Checked then + begin + Result := Format('%s -x radius,distance=%s', [Result, edWayptRadius.Text]); + if (cobWayptRadius.ItemIndex = 0) then + Result := Result + 'M' else + Result := Result + 'K'; + Result := Format('%s,lat=%s,lon=%s', [Result, edWayptRadiusLat.Text, edWayptRadiusLon.Text]); + end; + SimpleOption(Result, cbWayptSort, 'sort'); + end; + + if AnyChecked(gbTracks) then + begin + Result := Format('%s -x %s', [Result, 'track']); + if cbTrackTitle.Checked then + Result := Format('%s,title="%s"', [Result, edTrackTitleValue.Text]); + + if cbTrackTime.Checked then + begin + s := Format('%sd%sh%sm%ss', + [edTrackTimeDays.Text, edTrackTimeHours.Text, + edTrackTimeMinutes.Text, edTrackTimeSeconds.Text]); + if (s <> '0d0h0m0s') then + Result := Format('%s,move=%s', [Result, s]); + end; + + if cbTrackPack.Checked then + Result := Format('%s,pack', [Result]) + else if cbTrackMerge.Checked then + Result := Format('%s,merge', [Result]); + + if cbTrackSplit.Checked then + Result := Format('%s,split', [Result]); + + if (cbTrackRangeTimeZone.Enabled and cbTrackRangeTimeZone.Checked) then + begin + Windows.GetTimeZoneInformation(tz_Info); + tz_Info.Bias := tz_Info.Bias + tz_Info.DaylightBias; + dt_bias := tz_Info.Bias / (24*60); + end + else + dt_bias := 0.0; + + if cbTrackStart.Checked then + begin + dt := Int(dtpTrackStartDate.DateTime) + Frac(dtpTrackStartTime.DateTime) + dt_bias; + Result := Format('%s,start=%s', [ + Result, + FormatDateTime('yyyymmddhhnnss', dt)]); + end; + if cbTrackStop.Checked then + begin + dt := Int(dtpTrackStopDate.DateTime) + Frac(dtpTrackStopTime.DateTime) + dt_bias; + Result := Format('%s,stop=%s', [ + Result, + FormatDateTime('yyyymmddhhnnss', dt)]); + end; + if cbTrackFixes.Checked then + Result := Format('%s,fix', [Result]); + if cbTrackCourse.Checked then + Result := Format('%s,course', [Result]); + if cbTrackSpeed.Checked then + Result := Format('%s,speed', [Result]); + end; + + if AnyChecked(gbRoutes) then + begin + if cbRouteSimplify.Checked then + Result := Format('%s -x simplify,count=%s', + [Result, Trim(edRoutesSimplifyMaxPoints.Text)]); + + SimpleOption(Result, cbReverse, 'reverse'); + end; +end; + +function TfrmFilter.AnyChecked(Control: TWinControl): Boolean; +var + i: Integer; + c: TWinControl; +begin + Result := False; + for i := 0 to Self.ComponentCount - 1 do + begin + c := Pointer(Self.Components[i]); + if not(c.InheritsFrom(TWinControl)) then Continue; + if (c.parent <> Control) then Continue; + + if ((c is TCheckBox) and TCheckBox(c).Enabled) then + Result := TCheckBox(c).Checked else + if ((c is TGroupBox) and c.Enabled) then + Result := AnyChecked(c); + if (Result) then Exit; + end; +end; + +procedure TfrmFilter.SetTracksEnabled(const Value: Boolean); +begin + FTracksEnabled := Value; + gbTracks.Enabled := Value; +end; + +function TfrmFilter.AllValid: Boolean; +begin + Result := True; +end; + +procedure TfrmFilter.btnOKClick(Sender: TObject); +begin + if AllValid then + begin +// StoreSettingsToInifile(); + StoreSettingsToRegistry(); + ModalResult := mrOK; + end; +end; + +procedure TfrmFilter.cbTrackStartClick(Sender: TObject); +begin + dtpTrackStartDate.Enabled := cbTrackStart.Checked; + dtpTrackStartTime.Enabled := cbTrackStart.Checked; + cbTrackRangeTimeZone.Enabled := + cbTrackStart.Checked or cbTrackStop.Checked; +end; + +procedure TfrmFilter.cbTrackStopClick(Sender: TObject); +begin + dtpTrackStopDate.Enabled := cbTrackStop.Checked; + dtpTrackStopTime.Enabled := cbTrackStop.Checked; + cbTrackRangeTimeZone.Enabled := + cbTrackStart.Checked or cbTrackStop.Checked; +end; + +procedure TfrmFilter.cbRouteSimplifyClick(Sender: TObject); +begin + edRoutesSimplifyMaxPoints.Enabled := cbRouteSimplify.Checked; +end; + +procedure TfrmFilter.cbTrackPackClick(Sender: TObject); +begin + if cbTrackPack.Checked then + cbTrackMerge.Checked := False; +end; + +procedure TfrmFilter.cbTrackMergeClick(Sender: TObject); +begin + if cbTrackMerge.Checked then cbTrackPack.Checked := False; +end; + +procedure TfrmFilter.cbWayptMergeDistanceClick(Sender: TObject); +begin + edWayptMergeDist.Enabled := cbWayptMergeDistance.Checked; + cobWayptMergeDist.Enabled := cbWayptMergeDistance.Checked; +end; + +procedure TfrmFilter.cbWayptMergeDupsClick(Sender: TObject); +begin + cbWayptMergeDupLoc.Enabled := cbWayptMergeDups.Checked; + cbWayptMergeDupNames.Enabled := cbWayptMergeDups.Checked; +end; + +procedure TfrmFilter.cbWayptRadiusClick(Sender: TObject); +begin + edWayptRadius.Enabled := cbWayptRadius.Checked; + cobWayptRadius.Enabled := cbWayptRadius.Checked; + edWayptRadiusLat.Enabled := cbWayptRadius.Checked; + edWayptRadiusLon.Enabled := cbWayptRadius.Checked; +end; + +procedure TfrmFilter.FormCloseQuery(Sender: TObject; + var CanClose: Boolean); +begin + if (ModalResult <> mrOK) then + begin + ChangeCheckBoxesChecked(Self, True); + CanClose := True; + Exit; + end; + CanClose := + ValidateNumerical(edWayptRadius, 0, 99999) and + ValidateNumerical(edWayptRadiusLat, -180, 180) and + ValidateNumerical(edWayptRadiusLon, -90, 90) and + ValidateNumerical(edWayptMergeDist, 0, 99999999) and + ValidateNumerical(edRoutesSimplifyMaxPoints, 1, 9999); + ChangeCheckBoxesChecked(Self, False); +end; + +procedure TfrmFilter.FormShow(Sender: TObject); +begin + ChangeCheckBoxesChecked(Self); + FInitialValues := CmdLine; +end; + +procedure TfrmFilter.ChangeCheckBoxesChecked(AComponent: TComponent; Restore: Boolean = False); +var + i, j: Integer; + c: TComponent; +begin + j := AComponent.ComponentCount; + for i := 0 to j - 1 do + begin + c := AComponent.Components[i]; + if (c is TCheckBox) then + begin + if (Restore) then + TCheckBox(c).Checked := (c.Tag <> 0) else + c.Tag := Integer(TCheckBox(c).Checked); + end + else if (c.ComponentCount > 0) then + ChangeCheckBoxesChecked(c); + end; +end; + +procedure TfrmFilter.FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var + str: string; +begin + if (Key <> 27) then Exit; + + + str := Self.CmdLine; + if (str <> FInitialValues) then + begin + if not(MessageDlg(_('Discard changes?'), mtWarning, mbOKCancel, 0) = mrOK) then + Exit; + end; + ModalResult := mrCancel; +end; + +procedure TfrmFilter.btnHelpClick(Sender: TObject); +begin + WinOpenURL(readme_html_path + '#Data_Filters'); +end; + +procedure TfrmFilter.LoadSettingsFromInifile(); +var + c: TComponent; + i: Integer; + l: TStrings; + s: string; +begin +(* + l := TStringList.Create; + try + gpsbabel_ini.ReadSection('GPSBabelGUI', l); + for i := 0 to l.Count - 1 do + begin + s := l.Strings[i]; + c := SELF.FindComponent('cb' + s); + if (c <> nil) and (c is TCheckbox) then + TCheckbox(c).Checked := (gpsbabel_ini.ReadString('GPSBabelGUI', s, '0') <> '0'); + end; + edTrackTitleValue.Text := gpsbabel_ini.ReadString('track', 'title', + edTrackTitleValue.Text); + edRoutesSimplifyMaxPoints.Text := gpsbabel_ini.ReadString('simplify', 'count', + edRoutesSimplifyMaxPoints.Text); + finally + l.Free; + end; +*) +end; + +procedure TfrmFilter.StoreSettingsToInifile(); +var + i: Integer; + c: TComponent; +begin +(* + for i := 0 to SELF.ComponentCount - 1 do + begin + c := SELF.Components[i]; + if (c is TCheckBox) then + begin + if TCheckBox(c).Checked then + gpsbabel_ini.WriteString('GPSBabelGUI', Copy(TCheckbox(c).Name, 3, 256), '1') + else + gpsbabel_ini.DeleteKey('GPSBabelGUI', Copy(TCheckbox(c).Name, 3, 256)); + end; + end; + + if cbTrackTitle.Checked then + gpsbabel_ini.WriteString('track', 'title', edTrackTitleValue.Text) + else + gpsbabel_ini.DeleteKey('track', 'title'); + + if cbRouteSimplify.Checked then + gpsbabel_ini.WriteString('simplify', 'count', edRoutesSimplifyMaxPoints.Text) + else + gpsbabel_ini.DeleteKey('simplify', 'count'); +*) +end; + +procedure TfrmFilter.StoreSettingsToRegistry(); +var + i: Integer; + c: TComponent; + r: TRegistry; +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKey('\SOFTWARE\GPSBabel', True)) then Exit; + + for i := 0 to SELF.ComponentCount - 1 do + begin + c := SELF.Components[i]; + if (c is TCheckbox) then + r.WriteBool('filter:' + Copy(c.Name, 3, 256), TCheckBox(c).Checked) + else if (c is TEdit) then + r.WriteString('filter:' + Copy(c.Name, 3, 256), TEdit(c).Text); + end; + finally + r.Free; + end; +end; + +procedure TfrmFilter.LoadSettingsFromRegistry(); +var + i: Integer; + c: TComponent; + r: TRegistry; + s: string; + u: TUpDown; + + function ReadString(R: TRegistry; const Key, Def: string): string; + begin + if R.ValueExists(Key) then + Result := R.ReadString(Key) + else + Result := Def; + end; + +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKey('\SOFTWARE\GPSBabel', True)) then Exit; + + for i := 0 to SELF.ComponentCount - 1 do + begin + c := SELF.Components[i]; + try + if (c is TCheckbox) then + TCheckBox(c).Checked := r.ReadBool('filter:' + Copy(c.Name, 3, 256)) + else if (c is TEdit) then + begin + s := ReadString(r, 'filter:' + Copy(c.Name, 3, 256), TEdit(c).Text); + if HasUpDown(TEdit(c), u) then + u.Position := StrToInt(s) + else + TEdit(c).Text := s; + end; + except + on E: Exception do ; + end; + end; + finally + r.Free; + end; +end; + +procedure TfrmFilter.cbTransformClick(Sender: TObject); +begin + cobTransform.Enabled := cbTransform.Checked; +end; + +end. diff --git a/win32/gui-2/gnugettext.pas b/win32/gui-2/gnugettext.pas new file mode 100644 index 000000000..e81821bcf --- /dev/null +++ b/win32/gui-2/gnugettext.pas @@ -0,0 +1,2842 @@ +unit gnugettext; +(**************************************************************) +(* *) +(* (C) Copyright by Lars B. Dybdahl and others *) +(* E-mail: Lars@dybdahl.dk, phone +45 70201241 *) +(* File version: $Date: 2005/12/06 00:25:47 $ *) +(* Revision: $Revision: 1.3 $ *) +(* *) +(* Contributors: Peter Thornqvist, Troy Wolbrink, *) +(* Frank Andreas de Groot, Igor Siticov, *) +(* Jacques Garcia Vazquez *) +(* *) +(* See http://dybdahl.dk/dxgettext/ for more information *) +(* *) +(**************************************************************) + +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// The names of any contributor may not be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +interface + +// If the conditional define DXGETTEXTDEBUG is defined, debugging log is activated. +// Use DefaultInstance.DebugLogToFile() to write the log to a file. +{ $define DXGETTEXTDEBUG} + +{$ifdef VER100} + // Delphi 3 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER110} + // C++ Builder 3 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER120} + // Delphi 4 + {$DEFINE DELPHI4OROLDER} + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER125} + // C++ Builder 4 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$ifdef VER130} + // Delphi 5 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} + {$ifdef WIN32} + {$DEFINE MSWINDOWS} + {$endif} +{$endif} +{$ifdef VER135} + // C++ Builder 5 + {$DEFINE DELPHI5OROLDER} + {$DEFINE DELPHI6OROLDER} + {$ifdef WIN32} + {$DEFINE MSWINDOWS} + {$endif} +{$endif} +{$ifdef VER140} + // Delphi 6 +{$ifdef MSWINDOWS} + {$DEFINE DELPHI6OROLDER} +{$endif} +{$endif} +{$ifdef VER150} + // Delphi 7 +{$endif} + +uses + TypInfo, +{$ifdef DELPHI4OROLDER} + gnugettextD4, +{$else} + {$ifdef DELPHI5OROLDER} + gnugettextD5, + {$endif} +{$endif} + +{$ifdef MSWINDOWS} + Windows, + Delphi, +{$else} + Libc, +{$endif} + Classes, SysUtils; + +(*****************************************************************************) +(* *) +(* MAIN API *) +(* *) +(*****************************************************************************) + +// Main GNU gettext functions. See documentation for instructions on how to use them. +function _(const szMsgId: widestring): widestring; +function gettext(const szMsgId: widestring): widestring; +function dgettext(const szDomain: string; const szMsgId: widestring): widestring; +function dngettext(const szDomain: string; const singular,plural: widestring; Number:longint): widestring; +function ngettext(const singular,plural: widestring; Number:longint): widestring; +procedure textdomain(const szDomain: string); +function getcurrenttextdomain: string; +procedure bindtextdomain(const szDomain: string; const szDirectory: string); + +// Set language to use +procedure UseLanguage(LanguageCode: string); +function GetCurrentLanguage:string; + +// Translates a component (form, frame etc.) to the currently selected language. +// Put TranslateComponent(self) in the OnCreate event of all your forms. +// See the manual for documentation on these functions +type + TTranslator=procedure (obj:TObject) of object; + +procedure TP_Ignore(AnObject:TObject; const name:string); +procedure TP_IgnoreClass (IgnClass:TClass); +procedure TP_IgnoreClassProperty (IgnClass:TClass;const propertyname:string); +procedure TP_GlobalIgnoreClass (IgnClass:TClass); +procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;const propertyname:string); +procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator); +procedure TranslateComponent(AnObject: TComponent; const TextDomain:string=''); +procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string=''); + +// Add more domains that resourcestrings can be extracted from. If a translation +// is not found in the default domain, this domain will be searched, too. +// This is useful for adding mo files for certain runtime libraries and 3rd +// party component libraries +procedure AddDomainForResourceString (const domain:string); +procedure RemoveDomainForResourceString (const domain:string); + +// Unicode-enabled way to get resourcestrings, automatically translated +// Use like this: ws:=LoadResStringW(@NameOfResourceString); +function LoadResString(ResStringRec: PResStringRec): widestring; +function LoadResStringA(ResStringRec: PResStringRec): ansistring; +function LoadResStringW(ResStringRec: PResStringRec): widestring; + +// This returns an empty string if not translated or translator name is not specified. +function GetTranslatorNameAndEmail:widestring; + + +(*****************************************************************************) +(* *) +(* ADVANCED FUNCTIONALITY *) +(* *) +(*****************************************************************************) + +const + DefaultTextDomain = 'default'; + +var + ExecutableFilename:string; // This is set to paramstr(0) or the name of the DLL you are creating. + +type + EGnuGettext=class(Exception); + EGGProgrammingError=class(EGnuGettext); + EGGComponentError=class(EGnuGettext); + EGGIOError=class(EGnuGettext); + EGGAnsi2WideConvError=class(EGnuGettext); + +// This function will turn resourcestring hooks on or off, eventually with BPL file support. +// Please do not activate BPL file support when the package is in design mode. +const AutoCreateHooks=true; +procedure HookIntoResourceStrings (enabled:boolean=true; SupportPackages:boolean=false); + + + + +(*****************************************************************************) +(* *) +(* CLASS based implementation. *) +(* Use TGnuGettextInstance to have more than one language *) +(* in your application at the same time *) +(* *) +(*****************************************************************************) + +{$ifdef MSWINDOWS} +{$ifndef DELPHI6OROLDER} +{$WARN UNSAFE_TYPE OFF} +{$WARN UNSAFE_CODE OFF} +{$WARN UNSAFE_CAST OFF} +{$endif} +{$endif} + +type + TOnDebugLine = Procedure (Sender: TObject; const Line: String; var Discard: Boolean) of Object; // Set Discard to false if output should still go to ordinary debug log + TGetPluralForm=function (Number:Longint):Integer; + TDebugLogger=procedure (line: ansistring) of object; + TMoFile= // Don't use this class. It's for internal use. + class // Threadsafe. Only constructor and destructor are writing to memory + private + doswap: boolean; + public + Users:Integer; // Reference count. If it reaches zero, this object should be destroyed. + constructor Create (filename:string;Offset,Size:int64); + destructor Destroy; override; + function gettext(const msgid: ansistring;var found:boolean): ansistring; // uses mo file + property isSwappedArchitecture:boolean read doswap; + private + N, O, T: Cardinal; // Values defined at http://www.linuxselfhelp.com/gnu/gettext/html_chapter/gettext_6.html + startindex,startstep:integer; + {$ifdef mswindows} + mo: THandle; + momapping: THandle; + {$endif} + momemoryHandle:PChar; + momemory: PChar; + function autoswap32(i: cardinal): cardinal; + function CardinalInMem(baseptr: PChar; Offset: Cardinal): Cardinal; + end; + TDomain= // Don't use this class. It's for internal use. + class + private + Enabled:boolean; + vDirectory: string; + procedure setDirectory(const dir: string); + public + DebugLogger:TDebugLogger; + Domain: string; + property Directory: string read vDirectory write setDirectory; + constructor Create; + destructor Destroy; override; + // Set parameters + procedure SetLanguageCode (const langcode:string); + procedure SetFilename (const filename:string); // Bind this domain to a specific file + // Get information + procedure GetListOfLanguages(list:TStrings); + function GetTranslationProperty(Propertyname: string): WideString; + function gettext(const msgid: ansistring): ansistring; // uses mo file + private + mofile:TMoFile; + SpecificFilename:string; + curlang: string; + OpenHasFailedBefore: boolean; + procedure OpenMoFile; + procedure CloseMoFile; + end; + TExecutable= + class + procedure Execute; virtual; abstract; + end; + TGnuGettextInstance= + class + private + fOnDebugLine:TOnDebugLine; + CreatorThread:Cardinal; // Only this thread can use LoadResString + public + Enabled:Boolean; // Set this to false to disable translations + DesignTimeCodePage:Integer; // See MultiByteToWideChar() in Win32 API for documentation + constructor Create; + destructor Destroy; override; + procedure UseLanguage(LanguageCode: string); + procedure GetListOfLanguages (const domain:string; list:TStrings); // Puts list of language codes, for which there are translations in the specified domain, into list + {$ifdef DELPHI5OROLDER} + function gettext(const szMsgId: widestring): widestring; + function ngettext(const singular,plural:widestring;Number:longint):widestring; + {$endif} + {$ifndef DELPHI5OROLDER} + function gettext(const szMsgId: ansistring): widestring; overload; + function gettext(const szMsgId: widestring): widestring; overload; + function ngettext(const singular,plural:ansistring;Number:longint):widestring; overload; + function ngettext(const singular,plural:widestring;Number:longint):widestring; overload; + {$endif} + function GetCurrentLanguage:string; + function GetTranslationProperty (const Propertyname:string):WideString; + function GetTranslatorNameAndEmail:widestring; + + // Form translation tools, these are not threadsafe. All TP_ procs must be called just before TranslateProperites() + procedure TP_Ignore(AnObject:TObject; const name:string); + procedure TP_IgnoreClass (IgnClass:TClass); + procedure TP_IgnoreClassProperty (IgnClass:TClass;propertyname:string); + procedure TP_GlobalIgnoreClass (IgnClass:TClass); + procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;propertyname:string); + procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator); + procedure TranslateProperties(AnObject: TObject; textdomain:string=''); + procedure TranslateComponent(AnObject: TComponent; const TextDomain:string=''); + procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string=''); + + // Multi-domain functions + {$ifdef DELPHI5OROLDER} + function dgettext(const szDomain: string; const szMsgId: widestring): widestring; + function dngettext(const szDomain: string; const singular,plural:widestring;Number:longint):widestring; + {$endif} + {$ifndef DELPHI5OROLDER} + function dgettext(const szDomain: string; const szMsgId: ansistring): widestring; overload; + function dgettext(const szDomain: string; const szMsgId: widestring): widestring; overload; + function dngettext(const szDomain: string; const singular,plural:ansistring;Number:longint):widestring; overload; + function dngettext(const szDomain: string; const singular,plural:widestring;Number:longint):widestring; overload; + {$endif} + procedure textdomain(const szDomain: string); + function getcurrenttextdomain: string; + procedure bindtextdomain(const szDomain: string; const szDirectory: string); + procedure bindtextdomainToFile (const szDomain: string; const filename: string); // Also works with files embedded in exe file + + // Windows API functions + function LoadResString(ResStringRec: PResStringRec): widestring; + + // Output all log info to this file. This may only be called once. + procedure DebugLogToFile (const filename:string; append:boolean=false); + procedure DebugLogPause (PauseEnabled:boolean); + property OnDebugLine: TOnDebugLine read fOnDebugLine write fOnDebugLine; // If set, all debug output goes here + + // Conversion according to design-time character set + function ansi2wide (const s:ansistring):widestring; + protected + procedure TranslateStrings (sl:TStrings;const TextDomain:string); + + // Override these three, if you want to inherited from this class + // to create a new class that handles other domain and language dependent + // issues + procedure WhenNewLanguage (const LanguageID:string); virtual; // Override to know when language changes + procedure WhenNewDomain (const TextDomain:string); virtual; // Override to know when text domain changes. Directory is purely informational + procedure WhenNewDomainDirectory (const TextDomain,Directory:string); virtual; // Override to know when any text domain's directory changes. It won't be called if a domain is fixed to a specific file. + private + curlang: string; + curGetPluralForm:TGetPluralForm; + curmsgdomain: string; + savefileCS: TMultiReadExclusiveWriteSynchronizer; + savefile: TextFile; + savememory: TStringList; + DefaultDomainDirectory:string; + domainlist: TStringList; // List of domain names. Objects are TDomain. + TP_IgnoreList:TStringList; // Temporary list, reset each time TranslateProperties is called + TP_ClassHandling:TList; // Items are TClassMode. If a is derived from b, a comes first + TP_GlobalClassHandling:TList; // Items are TClassMode. If a is derived from b, a comes first + TP_Retranslator:TExecutable; // Cast this to TTP_Retranslator + DebugLogCS:TMultiReadExclusiveWriteSynchronizer; + DebugLog:TStream; + DebugLogOutputPaused:Boolean; + function TP_CreateRetranslator:TExecutable; // Must be freed by caller! + procedure FreeTP_ClassHandlingItems; + procedure DebugWriteln(line: ansistring); + procedure TranslateProperty(AnObject: TObject; PropInfo: PPropInfo; + TodoList: TStrings; const TextDomain:string); + function Getdomain(const domain, DefaultDomainDirectory, CurLang: string): TDomain; // Translates a single property of an object + end; + +var + DefaultInstance:TGnuGettextInstance; + +implementation + +(**************************************************************************) +// Some comments on the implementation: +// This unit should be independent of other units where possible. +// It should have a small footprint in any way. +(**************************************************************************) +// TMultiReadExclusiveWriteSynchronizer is used instead of TCriticalSection +// because it makes this unit independent of the SyncObjs unit +(**************************************************************************) + +{$ifdef DELPHI5OROLDER} +uses + FileCtrl; +{$endif} + +type + TTP_RetranslatorItem= + class + obj:TObject; + Propname:string; + OldValue:WideString; + end; + TTP_Retranslator= + class (TExecutable) + TextDomain:string; + Instance:TGnuGettextInstance; + constructor Create; + destructor Destroy; override; + procedure Remember (obj:TObject; PropName:String; OldValue:WideString); + procedure Execute; override; + private + list:TList; + end; + TEmbeddedFileInfo= + class + offset,size:int64; + end; + TFileLocator= + class // This class finds files even when embedded inside executable + constructor Create; + destructor Destroy; override; + procedure Analyze; // List files embedded inside executable + function FileExists (filename:string):boolean; + function GetMoFile (filename:string;DebugLogger:TDebugLogger):TMoFile; + procedure ReleaseMoFile (mofile:TMoFile); + private + basedirectory:string; + filelist:TStringList; //Objects are TEmbeddedFileInfo. Filenames are relative to .exe file + MoFilesCS:TMultiReadExclusiveWriteSynchronizer; + MoFiles:TStringList; // Objects are filenames+offset, objects are TMoFile + function ReadInt64 (str:TStream):int64; + end; + TGnuGettextComponentMarker= + class (TComponent) + public + LastLanguage:string; + Retranslator:TExecutable; + destructor Destroy; override; + end; + TClassMode= + class + HClass:TClass; + SpecialHandler:TTranslator; + PropertiesToIgnore:TStringList; // This is ignored if Handler is set + constructor Create; + destructor Destroy; override; + end; + TRStrinfo = record + strlength, stroffset: cardinal; + end; + TStrInfoArr = array[0..10000000] of TRStrinfo; + PStrInfoArr = ^TStrInfoArr; + TCharArray5=array[0..4] of ansichar; + THook= // Replaces a runtime library procedure with a custom procedure + class + public + constructor Create (OldProcedure, NewProcedure: pointer; FollowJump:boolean=false); + destructor Destroy; override; // Restores unhooked state + procedure Reset (FollowJump:boolean=false); // Disables and picks up patch points again + procedure Disable; + procedure Enable; + private + oldproc,newproc:Pointer; + Patch:TCharArray5; + Original:TCharArray5; + PatchPosition:PChar; + procedure Shutdown; // Same as destroy, except that object is not destroyed + end; + +var + // System information + Win32PlatformIsUnicode:boolean=False; + + // Information about files embedded inside .exe file + FileLocator:TFileLocator; + + // Hooks into runtime library functions + ResourceStringDomainListCS:TMultiReadExclusiveWriteSynchronizer; + ResourceStringDomainList:TStringList; + HookLoadResString:THook; + HookLoadStr:THook; + HookFmtLoadStr:THook; + +function GGGetEnvironmentVariable(const Name:string):string; +var + Len: integer; + W : String; +begin + Result := ''; + SetLength(W,1); + Len := Windows.GetEnvironmentVariable(PChar(Name), PChar(W), 1); + if Len > 0 then begin + SetLength(Result, Len - 1); + Windows.GetEnvironmentVariable(PChar(Name), PChar(Result), Len); + end; +end; + +function StripCR (s:string):string; +var + i:integer; +begin + i:=1; + while i<=length(s) do begin + if s[i]=#13 then delete (s,i,1) else inc (i); + end; + Result:=s; +end; + +function LF2LineBreakA (s:string):string; +{$ifdef MSWINDOWS} +var + i:integer; +{$endif} +begin + {$ifdef MSWINDOWS} + Assert (sLinebreak=#13#10); + i:=1; + while i<=length(s) do begin + if (s[i]=#10) and (copy(s,i-1,1)<>#13) then begin + insert (#13,s,i); + inc (i,2); + end else + inc (i); + end; + {$endif} + Result:=s; +end; + +function IsWriteProp(Info: PPropInfo): Boolean; +begin + Result := Assigned(Info) and (Info^.SetProc <> nil); +end; + +function string2csyntax(s: string): string; +// Converts a string to the syntax that is used in .po files +var + i: integer; + c: char; +begin + Result := ''; + for i := 1 to length(s) do begin + c := s[i]; + case c of + #32..#33, #35..#255: Result := Result + c; + #13: Result := Result + '\r'; + #10: Result := Result + '\n"'#13#10'"'; + #34: Result := Result + '\"'; + else + Result := Result + '\0x' + IntToHex(ord(c), 2); + end; + end; + Result := '"' + Result + '"'; +end; + +function ResourceStringGettext(MsgId: widestring): widestring; +var + i:integer; +begin + if (MsgID='') or (ResourceStringDomainListCS=nil) then begin + // This only happens during very complicated program startups that fail, + // or when Msgid='' + Result:=MsgId; + exit; + end; + ResourceStringDomainListCS.BeginRead; + try + for i:=0 to ResourceStringDomainList.Count-1 do begin + Result:=dgettext(ResourceStringDomainList.Strings[i], MsgId); + if Result<>MsgId then + break; + end; + finally + ResourceStringDomainListCS.EndRead; + end; +end; + +function gettext(const szMsgId: widestring): widestring; +begin + Result:=DefaultInstance.gettext(szMsgId); +end; + +function _(const szMsgId: widestring): widestring; +begin + Result:=DefaultInstance.gettext(szMsgId); +end; + +function dgettext(const szDomain: string; const szMsgId: widestring): widestring; +begin + Result:=DefaultInstance.dgettext(szDomain, szMsgId); +end; + +function dngettext(const szDomain: string; const singular,plural: widestring; Number:longint): widestring; +begin + Result:=DefaultInstance.dngettext(szDomain,singular,plural,Number); +end; + +function ngettext(const singular,plural: widestring; Number:longint): widestring; +begin + Result:=DefaultInstance.ngettext(singular,plural,Number); +end; + +procedure textdomain(const szDomain: string); +begin + DefaultInstance.textdomain(szDomain); +end; + +procedure SetGettextEnabled (enabled:boolean); +begin + DefaultInstance.Enabled:=enabled; +end; + +function getcurrenttextdomain: string; +begin + Result:=DefaultInstance.getcurrenttextdomain; +end; + +procedure bindtextdomain(const szDomain: string; const szDirectory: string); +begin + DefaultInstance.bindtextdomain(szDomain, szDirectory); +end; + +procedure TP_Ignore(AnObject:TObject; const name:string); +begin + DefaultInstance.TP_Ignore(AnObject, name); +end; + +procedure TP_GlobalIgnoreClass (IgnClass:TClass); +begin + DefaultInstance.TP_GlobalIgnoreClass(IgnClass); +end; + +procedure TP_IgnoreClass (IgnClass:TClass); +begin + DefaultInstance.TP_IgnoreClass(IgnClass); +end; + +procedure TP_IgnoreClassProperty (IgnClass:TClass;const propertyname:string); +begin + DefaultInstance.TP_IgnoreClassProperty(IgnClass,propertyname); +end; + +procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;const propertyname:string); +begin + DefaultInstance.TP_GlobalIgnoreClassProperty(IgnClass,propertyname); +end; + +procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator); +begin + DefaultInstance.TP_GlobalHandleClass (HClass, Handler); +end; + +procedure TranslateComponent(AnObject: TComponent; const TextDomain:string=''); +begin + DefaultInstance.TranslateComponent(AnObject, TextDomain); +end; + +procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string=''); +begin + DefaultInstance.RetranslateComponent(AnObject, TextDomain); +end; + +{$ifdef MSWINDOWS} + +// These constants are only used in Windows 95 +// Thanks to Frank Andreas de Groot for this table +const + IDAfrikaans = $0436; IDAlbanian = $041C; + IDArabicAlgeria = $1401; IDArabicBahrain = $3C01; + IDArabicEgypt = $0C01; IDArabicIraq = $0801; + IDArabicJordan = $2C01; IDArabicKuwait = $3401; + IDArabicLebanon = $3001; IDArabicLibya = $1001; + IDArabicMorocco = $1801; IDArabicOman = $2001; + IDArabicQatar = $4001; IDArabic = $0401; + IDArabicSyria = $2801; IDArabicTunisia = $1C01; + IDArabicUAE = $3801; IDArabicYemen = $2401; + IDArmenian = $042B; IDAssamese = $044D; + IDAzeriCyrillic = $082C; IDAzeriLatin = $042C; + IDBasque = $042D; IDByelorussian = $0423; + IDBengali = $0445; IDBulgarian = $0402; + IDBurmese = $0455; IDCatalan = $0403; + IDChineseHongKong = $0C04; IDChineseMacao = $1404; + IDSimplifiedChinese = $0804; IDChineseSingapore = $1004; + IDTraditionalChinese = $0404; IDCroatian = $041A; + IDCzech = $0405; IDDanish = $0406; + IDBelgianDutch = $0813; IDDutch = $0413; + IDEnglishAUS = $0C09; IDEnglishBelize = $2809; + IDEnglishCanadian = $1009; IDEnglishCaribbean = $2409; + IDEnglishIreland = $1809; IDEnglishJamaica = $2009; + IDEnglishNewZealand = $1409; IDEnglishPhilippines = $3409; + IDEnglishSouthAfrica = $1C09; IDEnglishTrinidad = $2C09; + IDEnglishUK = $0809; IDEnglishUS = $0409; + IDEnglishZimbabwe = $3009; IDEstonian = $0425; + IDFaeroese = $0438; IDFarsi = $0429; + IDFinnish = $040B; IDBelgianFrench = $080C; + IDFrenchCameroon = $2C0C; IDFrenchCanadian = $0C0C; + IDFrenchCotedIvoire = $300C; IDFrench = $040C; + IDFrenchLuxembourg = $140C; IDFrenchMali = $340C; + IDFrenchMonaco = $180C; IDFrenchReunion = $200C; + IDFrenchSenegal = $280C; IDSwissFrench = $100C; + IDFrenchWestIndies = $1C0C; IDFrenchZaire = $240C; + IDFrisianNetherlands = $0462; IDGaelicIreland = $083C; + IDGaelicScotland = $043C; IDGalician = $0456; + IDGeorgian = $0437; IDGermanAustria = $0C07; + IDGerman = $0407; IDGermanLiechtenstein = $1407; + IDGermanLuxembourg = $1007; IDSwissGerman = $0807; + IDGreek = $0408; IDGujarati = $0447; + IDHebrew = $040D; IDHindi = $0439; + IDHungarian = $040E; IDIcelandic = $040F; + IDIndonesian = $0421; IDItalian = $0410; + IDSwissItalian = $0810; IDJapanese = $0411; + IDKannada = $044B; IDKashmiri = $0460; + IDKazakh = $043F; IDKhmer = $0453; + IDKirghiz = $0440; IDKonkani = $0457; + IDKorean = $0412; IDLao = $0454; + IDLatvian = $0426; IDLithuanian = $0427; + IDMacedonian = $042F; IDMalaysian = $043E; + IDMalayBruneiDarussalam = $083E; IDMalayalam = $044C; + IDMaltese = $043A; IDManipuri = $0458; + IDMarathi = $044E; IDMongolian = $0450; + IDNepali = $0461; IDNorwegianBokmol = $0414; + IDNorwegianNynorsk = $0814; IDOriya = $0448; + IDPolish = $0415; IDBrazilianPortuguese = $0416; + IDPortuguese = $0816; IDPunjabi = $0446; + IDRhaetoRomanic = $0417; IDRomanianMoldova = $0818; + IDRomanian = $0418; IDRussianMoldova = $0819; + IDRussian = $0419; IDSamiLappish = $043B; + IDSanskrit = $044F; IDSerbianCyrillic = $0C1A; + IDSerbianLatin = $081A; IDSesotho = $0430; + IDSindhi = $0459; IDSlovak = $041B; + IDSlovenian = $0424; IDSorbian = $042E; + IDSpanishArgentina = $2C0A; IDSpanishBolivia = $400A; + IDSpanishChile = $340A; IDSpanishColombia = $240A; + IDSpanishCostaRica = $140A; IDSpanishDominicanRepublic = $1C0A; + IDSpanishEcuador = $300A; IDSpanishElSalvador = $440A; + IDSpanishGuatemala = $100A; IDSpanishHonduras = $480A; + IDMexicanSpanish = $080A; IDSpanishNicaragua = $4C0A; + IDSpanishPanama = $180A; IDSpanishParaguay = $3C0A; + IDSpanishPeru = $280A; IDSpanishPuertoRico = $500A; + IDSpanishModernSort = $0C0A; IDSpanish = $040A; + IDSpanishUruguay = $380A; IDSpanishVenezuela = $200A; + IDSutu = $0430; IDSwahili = $0441; + IDSwedishFinland = $081D; IDSwedish = $041D; + IDTajik = $0428; IDTamil = $0449; + IDTatar = $0444; IDTelugu = $044A; + IDThai = $041E; IDTibetan = $0451; + IDTsonga = $0431; IDTswana = $0432; + IDTurkish = $041F; IDTurkmen = $0442; + IDUkrainian = $0422; IDUrdu = $0420; + IDUzbekCyrillic = $0843; IDUzbekLatin = $0443; + IDVenda = $0433; IDVietnamese = $042A; + IDWelsh = $0452; IDXhosa = $0434; + IDZulu = $0435; + +function GetWindowsLanguage: string; +var + langid: Cardinal; + langcode: string; + CountryName: array[0..4] of char; + LanguageName: array[0..4] of char; + works: boolean; +begin + // The return value of GetLocaleInfo is compared with 3 = 2 characters and a zero + works := 3 = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, LanguageName, SizeOf(LanguageName)); + works := works and (3 = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, CountryName, + SizeOf(CountryName))); + if works then begin + // Windows 98, Me, NT4, 2000, XP and newer + LangCode := PChar(@LanguageName[0]); + if lowercase(LangCode)='no' then LangCode:='nb'; + LangCode:=LangCode + '_' + PChar(@CountryName[0]); + end else begin + // This part should only happen on Windows 95. + langid := GetThreadLocale; + case langid of + IDBelgianDutch: langcode := 'nl_BE'; + IDBelgianFrench: langcode := 'fr_BE'; + IDBrazilianPortuguese: langcode := 'pt_BR'; + IDDanish: langcode := 'da_DK'; + IDDutch: langcode := 'nl_NL'; + IDEnglishUK: langcode := 'en_GB'; + IDEnglishUS: langcode := 'en_US'; + IDFinnish: langcode := 'fi_FI'; + IDFrench: langcode := 'fr_FR'; + IDFrenchCanadian: langcode := 'fr_CA'; + IDGerman: langcode := 'de_DE'; + IDGermanLuxembourg: langcode := 'de_LU'; + IDGreek: langcode := 'el_GR'; + IDIcelandic: langcode := 'is_IS'; + IDItalian: langcode := 'it_IT'; + IDKorean: langcode := 'ko_KO'; + IDNorwegianBokmol: langcode := 'nb_NO'; + IDNorwegianNynorsk: langcode := 'nn_NO'; + IDPolish: langcode := 'pl_PL'; + IDPortuguese: langcode := 'pt_PT'; + IDRussian: langcode := 'ru_RU'; + IDSpanish, IDSpanishModernSort: langcode := 'es_ES'; + IDSwedish: langcode := 'sv_SE'; + IDSwedishFinland: langcode := 'sv_FI'; + else + langcode := 'C'; + end; + end; + Result := langcode; +end; +{$endif} + +function LoadResStringA(ResStringRec: PResStringRec): string; +begin + Result:=DefaultInstance.LoadResString(ResStringRec); +end; + +function GetTranslatorNameAndEmail:widestring; +begin + Result:=DefaultInstance.GetTranslatorNameAndEmail; +end; + +procedure UseLanguage(LanguageCode: string); +begin + DefaultInstance.UseLanguage(LanguageCode); +end; + +type + PStrData = ^TStrData; + TStrData = record + Ident: Integer; + Str: string; + end; + +function SysUtilsEnumStringModules(Instance: Longint; Data: Pointer): Boolean; +{$IFDEF MSWINDOWS} +var + Buffer: array [0..1023] of char; +begin + with PStrData(Data)^ do begin + SetString(Str, Buffer, + LoadString(Instance, Ident, Buffer, sizeof(Buffer))); + Result := Str = ''; + end; +end; +{$ENDIF} +{$IFDEF LINUX} +var + rs:TResStringRec; + Module:HModule; +begin + Module:=Instance; + rs.Module:=@Module; + with PStrData(Data)^ do begin + rs.Identifier:=Ident; + Str:=System.LoadResString(@rs); + Result:=Str=''; + end; +end; +{$ENDIF} + +function SysUtilsFindStringResource(Ident: Integer): string; +var + StrData: TStrData; +begin + StrData.Ident := Ident; + StrData.Str := ''; + EnumResourceModules(SysUtilsEnumStringModules, @StrData); + Result := StrData.Str; +end; + +function SysUtilsLoadStr(Ident: Integer): string; +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Sysutils.LoadRes('+IntToStr(ident)+') called'); + {$endif} + Result := ResourceStringGettext(SysUtilsFindStringResource(Ident)); +end; + +function SysUtilsFmtLoadStr(Ident: Integer; const Args: array of const): string; +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Sysutils.FmtLoadRes('+IntToStr(ident)+',Args) called'); + {$endif} + FmtStr(Result, SysUtilsFindStringResource(Ident), Args); + Result:=ResourceStringGettext(Result); +end; + +function LoadResString(ResStringRec: PResStringRec): widestring; +begin + Result:=DefaultInstance.LoadResString(ResStringRec); +end; + +function LoadResStringW(ResStringRec: PResStringRec): widestring; +begin + Result:=DefaultInstance.LoadResString(ResStringRec); +end; + + + +function GetCurrentLanguage:string; +begin + Result:=DefaultInstance.GetCurrentLanguage; +end; + +{ TDomain } + +procedure TDomain.CloseMoFile; +begin + if mofile<>nil then begin + FileLocator.ReleaseMoFile(mofile); + mofile:=nil; + end; + OpenHasFailedBefore:=False; +end; + +destructor TDomain.Destroy; +begin + CloseMoFile; + inherited; +end; + +{$ifdef mswindows} +function GetLastWinError:string; +var + errcode:Cardinal; +begin + SetLength (Result,2000); + errcode:=GetLastError(); + Windows.FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,errcode,0,PChar(Result),2000,nil); + Result:=StrPas(PChar(Result)); +end; +{$endif} + +procedure TDomain.OpenMoFile; +var + filename: string; +begin + // Check if it is already open + if mofile<>nil then + exit; + + // Check if it has been attempted to open the file before + if OpenHasFailedBefore then + exit; + + if SpecificFilename<>'' then + filename:=SpecificFilename + else begin + filename := Directory + curlang + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then + filename := Directory + copy(curlang, 1, 2) + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + end; + if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then begin + OpenHasFailedBefore:=True; + exit; + end; + mofile:=FileLocator.GetMoFile(filename, DebugLogger); + + {$ifdef DXGETTEXTDEBUG} + if mofile.isSwappedArchitecture then + DebugLogger ('.mo file is swapped (comes from another CPU architecture)'); + {$endif} + + // Check, that the contents of the file is utf-8 + if pos('CHARSET=UTF-8',uppercase(GetTranslationProperty('Content-Type')))=0 then begin + CloseMoFile; + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'); + {$endif} + {$ifdef MSWINDOWS} + MessageBox(0,PChar('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'),'Localization problem',MB_OK); + {$else} + writeln (stderr,'The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'); + {$endif} + Enabled:=False; + end; +end; + +function TDomain.GetTranslationProperty( + Propertyname: string): WideString; +var + sl:TStringList; + i:integer; + s:string; +begin + Propertyname:=uppercase(Propertyname)+': '; + sl:=TStringList.Create; + try + sl.Text:=utf8encode(gettext('')); + for i:=0 to sl.Count-1 do begin + s:=sl.Strings[i]; + if uppercase(copy(s,1,length(Propertyname)))=Propertyname then begin + Result:=utf8decode(trim(copy(s,length(PropertyName)+1,maxint))); + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('GetTranslationProperty('+PropertyName+') returns '''+Result+'''.'); + {$endif} + exit; + end; + end; + finally + FreeAndNil (sl); + end; + Result:=''; + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('GetTranslationProperty('+PropertyName+') did not find any value. An empty string is returned.'); + {$endif} +end; + +procedure TDomain.setDirectory(const dir: string); +begin + vDirectory := IncludeTrailingPathDelimiter(dir); + SpecificFilename:=''; + CloseMoFile; +end; + +procedure AddDomainForResourceString (const domain:string); +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Extra domain for resourcestring: '+domain); + {$endif} + ResourceStringDomainListCS.BeginWrite; + try + if ResourceStringDomainList.IndexOf(domain)=-1 then + ResourceStringDomainList.Add (domain); + finally + ResourceStringDomainListCS.EndWrite; + end; +end; + +procedure RemoveDomainForResourceString (const domain:string); +var + i:integer; +begin + {$ifdef DXGETTEXTDEBUG} + DefaultInstance.DebugWriteln ('Remove domain for resourcestring: '+domain); + {$endif} + ResourceStringDomainListCS.BeginWrite; + try + i:=ResourceStringDomainList.IndexOf(domain); + if i<>-1 then + ResourceStringDomainList.Delete (i); + finally + ResourceStringDomainListCS.EndWrite; + end; +end; + +procedure TDomain.SetLanguageCode(const langcode: string); +begin + CloseMoFile; + curlang:=langcode; +end; + +function GetPluralForm2EN(Number: Integer): Integer; +begin + Number:=abs(Number); + if Number=1 then Result:=0 else Result:=1; +end; + +function GetPluralForm1(Number: Integer): Integer; +begin + Result:=0; +end; + +function GetPluralForm2FR(Number: Integer): Integer; +begin + Number:=abs(Number); + if (Number=1) or (Number=0) then Result:=0 else Result:=1; +end; + +function GetPluralForm3LV(Number: Integer): Integer; +begin + Number:=abs(Number); + if (Number mod 10=1) and (Number mod 100<>11) then + Result:=0 + else + if Number<>0 then Result:=1 + else Result:=2; +end; + +function GetPluralForm3GA(Number: Integer): Integer; +begin + Number:=abs(Number); + if Number=1 then Result:=0 + else if Number=2 then Result:=1 + else Result:=2; +end; + +function GetPluralForm3LT(Number: Integer): Integer; +var + n1,n2:byte; +begin + Number:=abs(Number); + n1:=Number mod 10; + n2:=Number mod 100; + if (n1=1) and (n2<>11) then + Result:=0 + else + if (n1>=2) and ((n2<10) or (n2>=20)) then Result:=1 + else Result:=2; +end; + +function GetPluralForm3PL(Number: Integer): Integer; +var + n1,n2:byte; +begin + Number:=abs(Number); + n1:=Number mod 10; + n2:=Number mod 100; + if n1=1 then Result:=0 + else if (n1>=2) and (n1<=4) and ((n2<10) or (n2>=20)) then Result:=1 + else Result:=2; +end; + +function GetPluralForm3RU(Number: Integer): Integer; +var + n1,n2:byte; +begin + Number:=abs(Number); + n1:=Number mod 10; + n2:=Number mod 100; + if (n1=1) and (n2<>11) then + Result:=0 + else + if (n1>=2) and (n1<=4) and ((n2<10) or (n2>=20)) then Result:=1 + else Result:=2; +end; + +function GetPluralForm4SL(Number: Integer): Integer; +var + n2:byte; +begin + Number:=abs(Number); + n2:=Number mod 100; + if n2=1 then Result:=0 + else + if n2=2 then Result:=1 + else + if (n2=3) or (n2=4) then Result:=2 + else + Result:=3; +end; + +procedure TDomain.GetListOfLanguages(list: TStrings); +var + sr:TSearchRec; + more:boolean; + filename, path, langcode:string; + i, j:integer; +begin + list.Clear; + + // Iterate through filesystem + more:=FindFirst (Directory+'*',faAnyFile,sr)=0; + while more do begin + if (sr.Attr and faDirectory<>0) and (sr.name<>'.') and (sr.name<>'..') then begin + filename := Directory + sr.Name + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + if fileexists(filename) then begin + langcode:=lowercase(sr.name); + if list.IndexOf(langcode)=-1 then + list.Add(langcode); + end; + end; + more:=FindNext (sr)=0; + end; + + // Iterate through embedded files + for i:=0 to FileLocator.filelist.Count-1 do begin + filename:=FileLocator.basedirectory+FileLocator.filelist.Strings[i]; + path:=Directory; + {$ifdef MSWINDOWS} + path:=uppercase(path); + filename:=uppercase(filename); + {$endif} + j:=length(path); + if copy(filename,1,j)=path then begin + path:=PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo'; + {$ifdef MSWINDOWS} + path:=uppercase(path); + {$endif} + if copy(filename,length(filename)-length(path)+1,length(path))=path then begin + langcode:=lowercase(copy(filename,j+1,length(filename)-length(path)-j)); + if list.IndexOf(langcode)=-1 then + list.Add(langcode); + end; + end; + end; +end; + +procedure TDomain.SetFilename(const filename: string); +begin + CloseMoFile; + vDirectory := ''; + SpecificFilename:=filename; +end; + +function TDomain.gettext(const msgid: ansistring): ansistring; +var + found:boolean; +begin + if not Enabled then begin + Result:=msgid; + exit; + end; + if (mofile=nil) and (not OpenHasFailedBefore) then + OpenMoFile; + if mofile=nil then begin + {$ifdef DXGETTEXTDEBUG} + DebugLogger('.mo file is not open. Not translating "'+msgid+'"'); + {$endif} + Result := msgid; + end else begin + Result:=mofile.gettext(msgid,found); + {$ifdef DXGETTEXTDEBUG} + if found then + DebugLogger ('Found in .mo ('+Domain+'): "'+utf8encode(msgid)+'"->"'+utf8encode(Result)+'"') + else + DebugLogger ('Translation not found in .mo file ('+Domain+') : "'+utf8encode(msgid)+'"'); + {$endif} + end; +end; + +constructor TDomain.Create; +begin + inherited Create; + Enabled:=True; +end; + +{ TGnuGettextInstance } + +procedure TGnuGettextInstance.bindtextdomain(const szDomain, + szDirectory: string); +var + dir:string; +begin + dir:=IncludeTrailingPathDelimiter(szDirectory); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Text domain "'+szDomain+'" is now located at "'+dir+'"'); + {$endif} + getdomain(szDomain,DefaultDomainDirectory,CurLang).Directory := dir; + WhenNewDomainDirectory (szDomain, szDirectory); +end; + +constructor TGnuGettextInstance.Create; +begin + CreatorThread:=GetCurrentThreadId; + {$ifdef MSWindows} + DesignTimeCodePage:=CP_ACP; + {$endif} + {$ifdef DXGETTEXTDEBUG} + DebugLogCS:=TMultiReadExclusiveWriteSynchronizer.Create; + DebugLog:=TMemoryStream.Create; + DebugWriteln('Debug log started '+DateTimeToStr(Now)); + DebugWriteln(''); + {$endif} + curGetPluralForm:=GetPluralForm2EN; + Enabled:=True; + curmsgdomain:=DefaultTextDomain; + savefileCS := TMultiReadExclusiveWriteSynchronizer.Create; + domainlist := TStringList.Create; + TP_IgnoreList:=TStringList.Create; + TP_IgnoreList.Sorted:=True; + TP_GlobalClassHandling:=TList.Create; + TP_ClassHandling:=TList.Create; + + // Set some settings + DefaultDomainDirectory := IncludeTrailingPathDelimiter(extractfilepath(ExecutableFilename))+'locale'; + + UseLanguage(''); + + bindtextdomain(DefaultTextDomain, DefaultDomainDirectory); + textdomain(DefaultTextDomain); + + // Add default properties to ignore + TP_GlobalIgnoreClassProperty(TComponent,'Name'); + TP_GlobalIgnoreClassProperty(TCollection,'PropName'); +end; + +destructor TGnuGettextInstance.Destroy; +begin + if savememory <> nil then begin + savefileCS.BeginWrite; + try + CloseFile(savefile); + finally + savefileCS.EndWrite; + end; + FreeAndNil(savememory); + end; + FreeAndNil (savefileCS); + FreeAndNil (TP_IgnoreList); + while TP_GlobalClassHandling.Count<>0 do begin + TObject(TP_GlobalClassHandling.Items[0]).Free; + TP_GlobalClassHandling.Delete(0); + end; + FreeAndNil (TP_GlobalClassHandling); + FreeTP_ClassHandlingItems; + FreeAndNil (TP_ClassHandling); + while domainlist.Count <> 0 do begin + domainlist.Objects[0].Free; + domainlist.Delete(0); + end; + FreeAndNil(domainlist); + {$ifdef DXGETTEXTDEBUG} + FreeAndNil (DebugLog); + FreeAndNil (DebugLogCS); + {$endif} + inherited; +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.dgettext(const szDomain: string; const szMsgId: ansistring): widestring; +begin + Result:=dgettext(szDomain, ansi2wide(szMsgId)); +end; +{$endif} + +function TGnuGettextInstance.dgettext(const szDomain: string; + const szMsgId: widestring): widestring; +begin + if not Enabled then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translation has been disabled. Text is not being translated: '+szMsgid); + {$endif} + Result:=szMsgId; + end else begin + Result:=UTF8Decode(LF2LineBreakA(getdomain(szDomain,DefaultDomainDirectory,CurLang).gettext(StripCR(utf8encode(szMsgId))))); + {$ifdef DXGETTEXTDEBUG} + if (szMsgId<>'') and (Result='') then + DebugWriteln (Format('Error: Translation of %s was an empty string. This may never occur.',[szMsgId])); + {$endif} + end; +end; + +function TGnuGettextInstance.GetCurrentLanguage: string; +begin + Result:=curlang; +end; + +function TGnuGettextInstance.getcurrenttextdomain: string; +begin + Result := curmsgdomain; +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.gettext( + const szMsgId: ansistring): widestring; +begin + Result := dgettext(curmsgdomain, szMsgId); +end; +{$endif} + +function TGnuGettextInstance.gettext( + const szMsgId: widestring): widestring; +begin + Result := dgettext(curmsgdomain, szMsgId); +end; + +procedure TGnuGettextInstance.textdomain(const szDomain: string); +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Changed text domain to "'+szDomain+'"'); + {$endif} + curmsgdomain := szDomain; + WhenNewDomain (szDomain); +end; + +function TGnuGettextInstance.TP_CreateRetranslator : TExecutable; +var + ttpr:TTP_Retranslator; +begin + ttpr:=TTP_Retranslator.Create; + ttpr.Instance:=self; + TP_Retranslator:=ttpr; + Result:=ttpr; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('A retranslator was created.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_GlobalHandleClass(HClass: TClass; + Handler: TTranslator); +var + cm:TClassMode; + i:integer; +begin + for i:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode; + if cm.HClass=HClass then + raise EGGProgrammingError.Create ('You cannot set a handler for a class that has already been assigned otherwise.'); + if HClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=HClass; + cm.SpecialHandler:=Handler; + TP_GlobalClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('A handler was set for class '+HClass.ClassName+'.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=HClass; + cm.SpecialHandler:=Handler; + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('A handler was set for class '+HClass.ClassName+'.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_GlobalIgnoreClass(IgnClass: TClass); +var + cm:TClassMode; + i:integer; +begin + for i:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then + raise EGGProgrammingError.Create ('You cannot add a class to the ignore list that is already on that list: '+IgnClass.ClassName+'. You should keep all TP_Global functions in one place in your source code.'); + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_GlobalClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_GlobalIgnoreClassProperty( + IgnClass: TClass; propertyname: string); +var + cm:TClassMode; + i,idx:integer; +begin + propertyname:=uppercase(propertyname); + for i:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then begin + if Assigned(cm.SpecialHandler) then + raise EGGProgrammingError.Create ('You cannot ignore a class property for a class that has a handler set.'); + if not cm.PropertiesToIgnore.Find(propertyname,idx) then + cm.PropertiesToIgnore.Add(propertyname); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_GlobalClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_Ignore(AnObject: TObject; + const name: string); +begin + TP_IgnoreList.Add(uppercase(name)); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('On object with class name '+AnObject.ClassName+', ignore is set on '+name); + {$endif} +end; + +procedure TGnuGettextInstance.TranslateComponent(AnObject: TComponent; + const TextDomain: string); +var + comp:TGnuGettextComponentMarker; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + DebugWriteln ('TranslateComponent() was called for a component with name '+AnObject.Name+'.'); + {$endif} + comp:=AnObject.FindComponent('GNUgettextMarker') as TGnuGettextComponentMarker; + if comp=nil then begin + comp:=TGnuGettextComponentMarker.Create (nil); + comp.Name:='GNUgettextMarker'; + comp.Retranslator:=TP_CreateRetranslator; + TranslateProperties (AnObject, TextDomain); + AnObject.InsertComponent(comp); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('This is the first time, that this component has been translated. A retranslator component has been created for this component.'); + {$endif} + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('This is not the first time, that this component has been translated.'); + {$endif} + if comp.LastLanguage<>curlang then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ERROR: TranslateComponent() was called twice with different languages. This indicates an attempt to switch language at runtime, but by using TranslateComponent every time. This API has changed - please use RetranslateComponent() instead.'); + {$endif} + {$ifdef mswindows} + MessageBox (0,'This application tried to switch the language, but in an incorrect way. The programmer needs to replace a call to TranslateComponent with a call to RetranslateComponent(). The programmer should see the changelog of gnugettext.pas for more information.','Error',MB_OK); + {$else} + writeln (stderr,'This application tried to switch the language, but in an incorrect way. The programmer needs to replace a call to TranslateComponent with a call to RetranslateComponent(). The programmer should see the changelog of gnugettext.pas for more information.'); + {$endif} + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ERROR: TranslateComponent has been called twice, but with the same language chosen. This is a mistake, but in order to prevent that the application breaks, no exception is raised.'); + {$endif} + end; + end; + comp.LastLanguage:=curlang; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + {$endif} +end; + +procedure TGnuGettextInstance.TranslateProperty (AnObject:TObject; PropInfo:PPropInfo; TodoList:TStrings; const TextDomain:string); +var + {$ifdef DELPHI5OROLDER} + ws: string; + old: string; + {$endif} + {$ifndef DELPHI5OROLDER} + ppi:PPropInfo; + ws: WideString; + old: WideString; + {$endif} + obj:TObject; + Propname:string; +begin + PropName:=PropInfo^.Name; + try + // Translate certain types of properties + case PropInfo^.PropType^.Kind of + tkString, tkLString, tkWString: + begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translating '+AnObject.ClassName+'.'+PropName); + {$endif} + {$ifdef DELPHI5OROLDER} + old := GetStrProp(AnObject, PropName); + {$endif} + {$ifndef DELPHI5OROLDER} + if PropInfo^.PropType^.Kind<>tkWString then + old := ansi2wide(GetStrProp(AnObject, PropName)) + else + old := GetWideStrProp(AnObject, PropName); + {$endif} + {$ifdef DXGETTEXTDEBUG} + if old='' then + DebugWriteln ('(Empty, not translated)') + else + DebugWriteln ('Old value: "'+old+'"'); + {$endif} + if (old <> '') and (IsWriteProp(PropInfo)) then begin + if TP_Retranslator<>nil then + (TP_Retranslator as TTP_Retranslator).Remember(AnObject, PropName, old); + ws := dgettext(textdomain,old); + if ws <> old then begin + {$ifdef DELPHI5OROLDER} + SetStrProp(AnObject, PropName, ws); + {$endif} + {$ifndef DELPHI5OROLDER} + ppi:=GetPropInfo(AnObject, Propname); + if ppi<>nil then begin + SetWideStrProp(AnObject, ppi, ws); + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ERROR: Property disappeared: '+Propname+' for object of type '+AnObject.ClassName); + {$endif} + end; + {$endif} + end; + end; + end { case item }; + tkClass: + begin +// obj:=GetObjectProp(AnObject, PropName); +// if obj<>nil then +// TodoList.AddObject ('',obj); + end { case item }; + end { case }; + except + on E:Exception do + raise EGGComponentError.Create ('Property cannot be translated.'+sLineBreak+ + 'Add TP_GlobalIgnoreClassProperty('+AnObject.ClassName+','''+PropName+''') to your source code or use'+sLineBreak+ + 'TP_Ignore (self,''.'+PropName+''') to prevent this message.'+sLineBreak+ + 'Reason: '+e.Message); + end; +end; + +procedure TGnuGettextInstance.TranslateProperties(AnObject: TObject; textdomain:string=''); +var + TodoList:TStringList; // List of Name/TObject's that is to be processed + DoneList:TStringList; // List of hex codes representing pointers to objects that have been done + i, j, Count: integer; + PropList: PPropList; + UPropName: string; + PropInfo: PPropInfo; + comp:TComponent; + cm,currentcm:TClassMode; + ObjectPropertyIgnoreList:TStringList; + objid, Name:string; + {$ifdef DELPHI5OROLDER} + Data:PTypeData; + {$endif} +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('----------------------------------------------------------------------'); + DebugWriteln ('TranslateProperties() was called for an object of class '+AnObject.ClassName+' with domain "'+textdomain+'".'); + {$endif} + if textdomain='' then + textdomain:=curmsgdomain; + if TP_Retranslator<>nil then + (TP_Retranslator as TTP_Retranslator).TextDomain:=textdomain; + DoneList:=TStringList.Create; + TodoList:=TStringList.Create; + ObjectPropertyIgnoreList:=TStringList.Create; + try + TodoList.AddObject('', AnObject); + DoneList.Sorted:=True; + ObjectPropertyIgnoreList.Sorted:=True; + {$ifndef DELPHI5OROLDER} + ObjectPropertyIgnoreList.Duplicates:=dupIgnore; + ObjectPropertyIgnoreList.CaseSensitive:=False; + DoneList.Duplicates:=dupError; + DoneList.CaseSensitive:=True; + {$endif} + + while TodoList.Count<>0 do begin + AnObject:=TodoList.Objects[0]; + Name:=TodoList.Strings[0]; + TodoList.Delete(0); + if (AnObject<>nil) and (AnObject is TPersistent) then begin + // Make sure each object is only translated once + Assert (sizeof(integer)=sizeof(TObject)); + objid:=IntToHex(integer(AnObject),8); + if DoneList.Find(objid,i) then begin + continue; + end else begin + DoneList.Add(objid); + end; + + ObjectPropertyIgnoreList.Clear; + + // Find out if there is special handling of this object + currentcm:=nil; + // First check the local handling instructions + for j:=0 to TP_ClassHandling.Count-1 do begin + cm:=TObject(TP_ClassHandling.Items[j]) as TClassMode; + if AnObject.InheritsFrom(cm.HClass) then begin + if cm.PropertiesToIgnore.Count<>0 then begin + ObjectPropertyIgnoreList.AddStrings(cm.PropertiesToIgnore); + end else begin + // Ignore the entire class + currentcm:=cm; + break; + end; + end; + end; + // Then check the global handling instructions + if currentcm=nil then + for j:=0 to TP_GlobalClassHandling.Count-1 do begin + cm:=TObject(TP_GlobalClassHandling.Items[j]) as TClassMode; + if AnObject.InheritsFrom(cm.HClass) then begin + if cm.PropertiesToIgnore.Count<>0 then begin + ObjectPropertyIgnoreList.AddStrings(cm.PropertiesToIgnore); + end else begin + // Ignore the entire class + currentcm:=cm; + break; + end; + end; + end; + if currentcm<>nil then begin + ObjectPropertyIgnoreList.Clear; + // Ignore or use special handler + if Assigned(currentcm.SpecialHandler) then begin + currentcm.SpecialHandler (AnObject); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Special handler activated for '+AnObject.ClassName); + {$endif} + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Ignoring object '+AnObject.ClassName); + {$endif} + end; + continue; + end; + + {$ifdef DELPHI5OROLDER} + if AnObject.ClassInfo=nil then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('ClassInfo=nil encountered for class '+AnObject.ClassName+'. Translation of that component has stopped. You should ignore this object.'); + {$endif} + continue; + end; + Data := GetTypeData(AnObject.Classinfo); + Count := Data^.PropCount; + GetMem(PropList, Count * Sizeof(PPropInfo)); + {$endif} + {$ifndef DELPHI5OROLDER} + Count := GetPropList(AnObject, PropList); + {$endif} + try + {$ifdef DELPHI5OROLDER} + GetPropInfos(AnObject.ClassInfo, PropList); + {$endif} + for j := 0 to Count - 1 do begin + PropInfo := PropList[j]; + UPropName:=uppercase(PropInfo^.Name); + // Ignore properties that are meant to be ignored + if ((currentcm=nil) or (not currentcm.PropertiesToIgnore.Find(UPropName,i))) and + (not TP_IgnoreList.Find(Name+'.'+UPropName,i)) and + (not ObjectPropertyIgnoreList.Find(UPropName,i)) then begin + TranslateProperty (AnObject,PropInfo,TodoList,TextDomain); + end; // if + end; // for + finally + {$ifdef DELPHI5OROLDER} + FreeMem(PropList, Data^.PropCount * Sizeof(PPropInfo)); + {$endif} + {$ifndef DELPHI5OROLDER} + if Count<>0 then + FreeMem (PropList); + {$endif} + end; + if AnObject is TStrings then begin + if ((AnObject as TStrings).Text<>'') and (TP_Retranslator<>nil) then + (TP_Retranslator as TTP_Retranslator).Remember(AnObject, 'Text', (AnObject as TStrings).Text); + TranslateStrings (AnObject as TStrings,TextDomain); + end; + // Check for TCollection + if AnObject is TCollection then begin + for i := 0 to (AnObject as TCollection).Count - 1 do + TodoList.AddObject('',(AnObject as TCollection).Items[i]); + end; + if AnObject is TComponent then begin + for i := 0 to TComponent(AnObject).ComponentCount - 1 do begin + comp:=TComponent(AnObject).Components[i]; + if (not TP_IgnoreList.Find(uppercase(comp.Name),j)) then begin + TodoList.AddObject(uppercase(comp.Name),comp); + end; + end; + end; + end { if AnObject<>nil }; + end { while todolist.count<>0 }; + finally + FreeAndNil (todolist); + FreeAndNil (ObjectPropertyIgnoreList); + FreeAndNil (DoneList); + end; + FreeTP_ClassHandlingItems; + TP_IgnoreList.Clear; + TP_Retranslator:=nil; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('----------------------------------------------------------------------'); + {$endif} +end; + +procedure TGnuGettextInstance.UseLanguage(LanguageCode: string); +var + i,p:integer; + dom:TDomain; + l2:string[2]; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln('UseLanguage('''+LanguageCode+'''); called'); + {$endif} + + if LanguageCode='' then begin + LanguageCode:=GGGetEnvironmentVariable('LANG'); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('LANG env variable is '''+LanguageCode+'''.'); + {$endif} + {$ifdef MSWINDOWS} + if LanguageCode='' then begin + LanguageCode:=GetWindowsLanguage; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Found Windows language code to be '''+LanguageCode+'''.'); + {$endif} + end; + {$endif} + p:=pos('.',LanguageCode); + if p<>0 then + LanguageCode:=copy(LanguageCode,1,p-1); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Language code that will be set is '''+LanguageCode+'''.'); + {$endif} + end; + + curlang := LanguageCode; + for i:=0 to domainlist.Count-1 do begin + dom:=domainlist.Objects[i] as TDomain; + dom.SetLanguageCode (curlang); + end; + + l2:=lowercase(copy(curlang,1,2)); + if (l2='en') or (l2='de') then curGetPluralForm:=GetPluralForm2EN else + if (l2='hu') or (l2='ko') or (l2='zh') or (l2='ja') or (l2='tr') then curGetPluralForm:=GetPluralForm1 else + if (l2='fr') or (l2='fa') or (lowercase(curlang)='pt_br') then curGetPluralForm:=GetPluralForm2FR else + if (l2='lv') then curGetPluralForm:=GetPluralForm3LV else + if (l2='ga') then curGetPluralForm:=GetPluralForm3GA else + if (l2='lt') then curGetPluralForm:=GetPluralForm3LT else + if (l2='ru') or (l2='cs') or (l2='sk') or (l2='uk') or (l2='hr') then curGetPluralForm:=GetPluralForm3RU else + if (l2='pl') then curGetPluralForm:=GetPluralForm3PL else + if (l2='sl') then curGetPluralForm:=GetPluralForm4SL else begin + curGetPluralForm:=GetPluralForm2EN; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Plural form for the language was not found. English plurality system assumed.'); + {$endif} + end; + + WhenNewLanguage (curlang); + + {$ifdef DXGETTEXTDEBUG} + DebugWriteln(''); + {$endif} +end; + +procedure TGnuGettextInstance.TranslateStrings(sl: TStrings;const TextDomain:string); +var + line: string; + i: integer; + s:TStringList; +begin + if sl.Count > 0 then begin + sl.BeginUpdate; + try + s:=TStringList.Create; + try + s.Assign (sl); + for i:=0 to s.Count-1 do begin + line:=s.Strings[i]; + if line<>'' then + s.Strings[i]:=dgettext(TextDomain,line); + end; + sl.Assign(s); + finally + FreeAndNil (s); + end; + finally + sl.EndUpdate; + end; + end; +end; + +function TGnuGettextInstance.GetTranslatorNameAndEmail: widestring; +begin + Result:=GetTranslationProperty('LAST-TRANSLATOR'); +end; + +function TGnuGettextInstance.GetTranslationProperty( + const Propertyname: string): WideString; +begin + Result:=getdomain(curmsgdomain,DefaultDomainDirectory,CurLang).GetTranslationProperty (Propertyname); +end; + +function TGnuGettextInstance.dngettext(const szDomain: string; const singular, plural: widestring; + Number: Integer): widestring; +var + org,trans:widestring; + idx:integer; + p:integer; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('dngettext translation (domain '+szDomain+', number is '+IntTostr(Number)+') of '+singular+'/'+plural); + {$endif} + org:=singular+#0+plural; + trans:=dgettext(szDomain,org); + if org=trans then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translation was equal to english version. English plural forms assumed.'); + {$endif} + idx:=GetPluralForm2EN(Number) + end else + idx:=curGetPluralForm(Number); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Index '+IntToStr(idx)+' will be used'); + {$endif} + while true do begin + p:=pos(#0,trans); + if p=0 then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Last translation used: '+utf8encode(trans)); + {$endif} + Result:=trans; + exit; + end; + if idx=0 then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Translation found: '+utf8encode(trans)); + {$endif} + Result:=copy(trans,1,p-1); + exit; + end; + delete (trans,1,p); + dec (idx); + end; +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.ngettext(const singular, plural: ansistring; + Number: Integer): widestring; +begin + Result := dngettext(curmsgdomain, singular, plural, Number); +end; +{$endif} + +function TGnuGettextInstance.ngettext(const singular, plural: widestring; + Number: Integer): widestring; +begin + Result := dngettext(curmsgdomain, singular, plural, Number); +end; + +procedure TGnuGettextInstance.WhenNewDomain(const TextDomain: string); +begin + // This is meant to be empty. +end; + +procedure TGnuGettextInstance.WhenNewLanguage(const LanguageID: string); +begin + // This is meant to be empty. +end; + +procedure TGnuGettextInstance.WhenNewDomainDirectory(const TextDomain, + Directory: string); +begin + // This is meant to be empty. +end; + +procedure TGnuGettextInstance.GetListOfLanguages(const domain: string; + list: TStrings); +begin + getdomain(Domain,DefaultDomainDirectory,CurLang).GetListOfLanguages(list); +end; + +procedure TGnuGettextInstance.bindtextdomainToFile(const szDomain, + filename: string); +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Text domain "'+szDomain+'" is now bound to file named "'+filename+'"'); + {$endif} + getdomain(szDomain,DefaultDomainDirectory,CurLang).SetFilename (filename); +end; + +procedure TGnuGettextInstance.DebugLogPause(PauseEnabled: boolean); +begin + DebugLogOutputPaused:=PauseEnabled; +end; + +procedure TGnuGettextInstance.DebugLogToFile(const filename: string; append:boolean=false); +{$ifdef DXGETTEXTDEBUG} +var + fs:TFileStream; + marker:string; +{$endif} +begin + {$ifdef DXGETTEXTDEBUG} + // Create the file if needed + if (not fileexists(filename)) or (not append) then + fileclose (filecreate (filename)); + + // Open file + fs:=TFileStream.Create (filename,fmOpenWrite or fmShareDenyWrite); + if append then + fs.Seek(0,soFromEnd); + + // Write header if appending + if fs.Position<>0 then begin + marker:=sLineBreak+'==========================================================================='+sLineBreak; + fs.WriteBuffer(marker[1],length(marker)); + end; + + // Copy the memorystream contents to the file + DebugLog.Seek(0,soFromBeginning); + fs.CopyFrom(DebugLog,0); + + // Make DebugLog point to the filestream + FreeAndNil (DebugLog); + DebugLog:=fs; +{$endif} +end; + +procedure TGnuGettextInstance.DebugWriteln(line: ansistring); +Var + Discard: Boolean; +begin + Assert (DebugLogCS<>nil); + Assert (DebugLog<>nil); + + DebugLogCS.BeginWrite; + try + if DebugLogOutputPaused then + exit; + + if Assigned (fOnDebugLine) then begin + Discard := True; + fOnDebugLine (Self, Line, Discard); + If Discard then Exit; + end; + + line:=line+sLineBreak; + + // Ensure that memory usage doesn't get too big. + if (DebugLog is TMemoryStream) and (DebugLog.Position>1000000) then begin + line:=sLineBreak+sLineBreak+sLineBreak+sLineBreak+sLineBreak+ + 'Debug log halted because memory usage grew too much.'+sLineBreak+ + 'Specify a filename to store the debug log in or disable debug loggin in gnugettext.pas.'+ + sLineBreak+sLineBreak+sLineBreak+sLineBreak+sLineBreak; + DebugLogOutputPaused:=True; + end; + DebugLog.WriteBuffer(line[1],length(line)); + finally + DebugLogCS.EndWrite; + end; +end; + +function TGnuGettextInstance.Getdomain(const domain, DefaultDomainDirectory, CurLang: string): TDomain; +// Retrieves the TDomain object for the specified domain. +// Creates one, if none there, yet. +var + idx: integer; +begin + idx := domainlist.IndexOf(Domain); + if idx = -1 then begin + Result := TDomain.Create; + Result.DebugLogger:=DebugWriteln; + Result.Domain := Domain; + Result.Directory := DefaultDomainDirectory; + Result.SetLanguageCode(curlang); + domainlist.AddObject(Domain, Result); + end else begin + Result := domainlist.Objects[idx] as TDomain; + end; +end; + +function TGnuGettextInstance.LoadResString( + ResStringRec: PResStringRec): widestring; +{$ifdef MSWINDOWS} +var + Len: Integer; + Buffer: array [0..1023] of char; +{$endif} +{$ifdef LINUX } +const + ResStringTableLen = 16; +type + ResStringTable = array [0..ResStringTableLen-1] of LongWord; +var + Handle: TResourceHandle; + Tab: ^ResStringTable; + ResMod: HMODULE; +{$endif } +begin + if ResStringRec=nil then + exit; + if ResStringRec.Identifier>=64*1024 then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('LoadResString was given an invalid ResStringRec.Identifier'); + {$endif} + Result:='ERROR'; + exit; + end else begin + {$ifdef LINUX} + // This works with Unicode if the Linux has utf-8 character set + // Result:=System.LoadResString(ResStringRec); + ResMod:=FindResourceHInstance(ResStringRec^.Module^); + Handle:=FindResource(ResMod, + PChar(ResStringRec^.Identifier div ResStringTableLen), PChar(6)); // RT_STRING + Tab:=Pointer(LoadResource(ResMod, Handle)); + if Tab=nil then + Result:='' + else + Result:=PWideChar(PChar(Tab)+Tab[ResStringRec^.Identifier mod ResStringTableLen]); + {$endif} + {$ifdef MSWINDOWS} + if not Win32PlatformIsUnicode then begin + SetString(Result, Buffer, + LoadString(FindResourceHInstance(ResStringRec.Module^), + ResStringRec.Identifier, Buffer, SizeOf(Buffer))) + end else begin + Result := ''; + Len := 0; + While Len = Length(Result) do begin + if Length(Result) = 0 then + SetLength(Result, 1024) + else + SetLength(Result, Length(Result) * 2); + Len := LoadStringW(FindResourceHInstance(ResStringRec.Module^), + ResStringRec.Identifier, PWideChar(Result), Length(Result)); + end; + SetLength(Result, Len); + end; + {$endif} + end; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Loaded resourcestring: '+utf8encode(Result)); + {$endif} + if CreatorThread<>GetCurrentThreadId then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('LoadResString was called from an invalid thread. Resourcestring was not translated.'); + {$endif} + end else + Result:=ResourceStringGettext(Result); +end; + +procedure TGnuGettextInstance.RetranslateComponent(AnObject: TComponent; + const TextDomain: string); +var + comp:TGnuGettextComponentMarker; +begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + DebugWriteln ('RetranslateComponent() was called for a component with name '+AnObject.Name+'.'); + {$endif} + comp:=AnObject.FindComponent('GNUgettextMarker') as TGnuGettextComponentMarker; + if comp=nil then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Retranslate was called on an object that has not been translated before. An Exception is being raised.'); + {$endif} + raise EGGProgrammingError.Create ('Retranslate was called on an object that has not been translated before. Please use TranslateComponent() before RetranslateComponent().'); + end else begin + if comp.LastLanguage<>curlang then begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('The retranslator is being executed.'); + {$endif} + comp.Retranslator.Execute; + end else begin + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('The language has not changed. The retranslator is not executed.'); + {$endif} + end; + end; + comp.LastLanguage:=curlang; + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('======================================================================'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_IgnoreClass(IgnClass: TClass); +var + cm:TClassMode; + i:integer; +begin + for i:=0 to TP_ClassHandling.Count-1 do begin + cm:=TObject(TP_ClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then + raise EGGProgrammingError.Create ('You cannot add a class to the ignore list that is already on that list: '+IgnClass.ClassName+'.'); + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_ClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + TP_ClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.TP_IgnoreClassProperty(IgnClass: TClass; + propertyname: string); +var + cm:TClassMode; + i:integer; +begin + propertyname:=uppercase(propertyname); + for i:=0 to TP_ClassHandling.Count-1 do begin + cm:=TObject(TP_ClassHandling.Items[i]) as TClassMode; + if cm.HClass=IgnClass then begin + if Assigned(cm.SpecialHandler) then + raise EGGProgrammingError.Create ('You cannot ignore a class property for a class that has a handler set.'); + cm.PropertiesToIgnore.Add(propertyname); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + if IgnClass.InheritsFrom(cm.HClass) then begin + // This is the place to insert this class + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_ClassHandling.Insert(i,cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} + exit; + end; + end; + cm:=TClassMode.Create; + cm.HClass:=IgnClass; + cm.PropertiesToIgnore.Add(propertyname); + TP_GlobalClassHandling.Add(cm); + {$ifdef DXGETTEXTDEBUG} + DebugWriteln ('Locally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.'); + {$endif} +end; + +procedure TGnuGettextInstance.FreeTP_ClassHandlingItems; +begin + while TP_ClassHandling.Count<>0 do begin + TObject(TP_ClassHandling.Items[0]).Free; + TP_ClassHandling.Delete(0); + end; +end; + +function TGnuGettextInstance.ansi2wide(const s: ansistring): widestring; +{$ifdef MSWindows} +var + len:integer; +{$endif} +begin +{$ifdef MSWindows} + if DesignTimeCodePage=CP_ACP then begin + // No design-time codepage specified. Using runtime codepage instead. +{$endif} + Result:=s; +{$ifdef MSWindows} + end else begin + len:=length(s); + if len=0 then + Result:='' + else begin + SetLength (Result,len); + len:=MultiByteToWideChar(DesignTimeCodePage,0,pchar(s),len,pwidechar(Result),len); + if len=0 then + raise EGGAnsi2WideConvError.Create ('Cannot convert string to widestring:'+sLineBreak+s); + SetLength (Result,len); + end; + end; +{$endif} +end; + +{$ifndef DELPHI5OROLDER} +function TGnuGettextInstance.dngettext(const szDomain: string; const singular, + plural: ansistring; Number: Integer): widestring; +begin + Result:=dngettext (szDomain, ansi2wide(singular), ansi2wide(plural), Number); +end; +{$endif} + +{ TClassMode } + +constructor TClassMode.Create; +begin + PropertiesToIgnore:=TStringList.Create; + PropertiesToIgnore.Sorted:=True; + PropertiesToIgnore.Duplicates:=dupError; + {$ifndef DELPHI5OROLDER} + PropertiesToIgnore.CaseSensitive:=False; + {$endif} +end; + +destructor TClassMode.Destroy; +begin + FreeAndNil (PropertiesToIgnore); + inherited; +end; + +{ TFileLocator } + +procedure TFileLocator.Analyze; +var + s:ansistring; + i:integer; + offset:int64; + fs:TFileStream; + fi:TEmbeddedFileInfo; + filename:string; +begin + s:='6637DB2E-62E1-4A60-AC19-C23867046A89'#0#0#0#0#0#0#0#0; + s:=copy(s,length(s)-7,8); + offset:=0; + for i:=8 downto 1 do + offset:=offset shl 8+ord(s[i]); + if offset=0 then + exit; + BaseDirectory:=ExtractFilePath(ExecutableFilename); + try + fs:=TFileStream.Create(ExecutableFilename,fmOpenRead or fmShareDenyNone); + try + while true do begin + fs.Seek(offset,soFromBeginning); + offset:=ReadInt64(fs); + if offset=0 then + exit; + fi:=TEmbeddedFileInfo.Create; + try + fi.Offset:=ReadInt64(fs); + fi.Size:=ReadInt64(fs); + SetLength (filename, offset-fs.position); + fs.ReadBuffer (filename[1],offset-fs.position); + filename:=trim(filename); + filelist.AddObject(filename,fi); + except + FreeAndNil (fi); + raise; + end; + end; + finally + FreeAndNil (fs); + end; + except + {$ifdef DXGETTEXTDEBUG} + raise; + {$endif} + end; +end; + +constructor TFileLocator.Create; +begin + MoFilesCS:=TMultiReadExclusiveWriteSynchronizer.Create; + MoFiles:=TStringList.Create; + filelist:=TStringList.Create; + {$ifdef LINUX} + filelist.Duplicates:=dupError; + filelist.CaseSensitive:=True; + {$endif} + MoFiles.Sorted:=True; + {$ifndef DELPHI5OROLDER} + MoFiles.Duplicates:=dupError; + MoFiles.CaseSensitive:=False; + {$ifdef MSWINDOWS} + filelist.Duplicates:=dupError; + filelist.CaseSensitive:=False; + {$endif} + {$endif} + filelist.Sorted:=True; +end; + +destructor TFileLocator.Destroy; +begin + while filelist.count<>0 do begin + filelist.Objects[0].Free; + filelist.Delete (0); + end; + FreeAndNil (filelist); + FreeAndNil (MoFiles); + FreeAndNil (MoFilesCS); + inherited; +end; + +function TFileLocator.FileExists(filename: string): boolean; +var + idx:integer; +begin + if copy(filename,1,length(basedirectory))=basedirectory then + filename:=copy(filename,length(basedirectory)+1,maxint); + Result:=filelist.Find(filename,idx); +end; + +function TFileLocator.GetMoFile(filename: string; DebugLogger:TDebugLogger): TMoFile; +var + fi:TEmbeddedFileInfo; + idx:integer; + idxname:string; + Offset, Size: Int64; + realfilename:string; +begin + // Find real filename + offset:=0; + size:=0; + realfilename:=filename; + if copy(filename,1,length(basedirectory))=basedirectory then begin + filename:=copy(filename,length(basedirectory)+1,maxint); + idx:=filelist.IndexOf(filename); + if idx<>-1 then begin + fi:=filelist.Objects[idx] as TEmbeddedFileInfo; + realfilename:=ExecutableFilename; + offset:=fi.offset; + size:=fi.size; + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('Instead of '+filename+', using '+realfilename+' from offset '+IntTostr(offset)+', size '+IntToStr(size)); + {$endif} + end; + end; + + + {$ifdef DXGETTEXTDEBUG} + DebugLogger ('Reading .mo data from file '''+filename+''''); + {$endif} + + // Find TMoFile object + MoFilesCS.BeginWrite; + try + idxname:=realfilename+#1+IntToStr(offset); + if MoFiles.Find(idxname, idx) then begin + Result:=MoFiles.Objects[idx] as TMoFile; + end else begin + Result:=TMoFile.Create (realfilename, Offset, Size); + MoFiles.AddObject(idxname, Result); + end; + Inc (Result.Users); + finally + MoFilesCS.EndWrite; + end; +end; + +function TFileLocator.ReadInt64(str: TStream): int64; +begin + Assert (sizeof(Result)=8); + str.ReadBuffer(Result,8); +end; + +procedure TFileLocator.ReleaseMoFile(mofile: TMoFile); +var + i:integer; +begin + Assert (mofile<>nil); + + MoFilesCS.BeginWrite; + try + dec (mofile.Users); + if mofile.Users<=0 then begin + i:=MoFiles.Count-1; + while i>=0 do begin + if MoFiles.Objects[i]=mofile then begin + MoFiles.Delete(i); + FreeAndNil (mofile); + break; + end; + dec (i); + end; + end; + finally + MoFilesCS.EndWrite; + end; +end; + +{ TTP_Retranslator } + +constructor TTP_Retranslator.Create; +begin + list:=TList.Create; +end; + +destructor TTP_Retranslator.Destroy; +var + i:integer; +begin + for i:=0 to list.Count-1 do + TObject(list.Items[i]).Free; + FreeAndNil (list); + inherited; +end; + +procedure TTP_Retranslator.Execute; +var + i:integer; + sl:TStrings; + item:TTP_RetranslatorItem; + newvalue:WideString; + {$ifndef DELPHI5OROLDER} + ppi:PPropInfo; + {$endif} +begin + for i:=0 to list.Count-1 do begin + item:=TObject(list.items[i]) as TTP_RetranslatorItem; + if item.obj is TStrings then begin + // Since we don't know the order of items in sl, and don't have + // the original .Objects[] anywhere, we cannot anticipate anything + // about the current sl.Strings[] and sl.Objects[] values. We therefore + // have to discard both values. We can, however, set the original .Strings[] + // value into the list and retranslate that. + sl:=TStringList.Create; + try + sl.Text:=item.OldValue; + Instance.TranslateStrings(sl,textdomain); + (item.obj as TStrings).BeginUpdate; + try + (item.obj as TStrings).Text:=sl.Text; + finally + (item.obj as TStrings).EndUpdate; + end; + finally + FreeAndNil (sl); + end; + end else begin + newValue:=instance.dgettext(textdomain,item.OldValue); + {$ifdef DELPHI5OROLDER} + SetStrProp(item.obj, item.PropName, newValue); + {$endif} + {$ifndef DELPHI5OROLDER} + ppi:=GetPropInfo(item.obj, item.Propname); + if ppi<>nil then begin + SetWideStrProp(item.obj, ppi, newValue); + end else begin + {$ifdef DXGETTEXTDEBUG} + Instance.DebugWriteln ('ERROR: On retranslation, property disappeared: '+item.Propname+' for object of type '+item.obj.ClassName); + {$endif} + end; + {$endif} + end; + end; +end; + +procedure TTP_Retranslator.Remember(obj: TObject; PropName: String; + OldValue: WideString); +var + item:TTP_RetranslatorItem; +begin + item:=TTP_RetranslatorItem.Create; + item.obj:=obj; + item.Propname:=Propname; + item.OldValue:=OldValue; + list.Add(item); +end; + +{ TGnuGettextComponentMarker } + +destructor TGnuGettextComponentMarker.Destroy; +begin + FreeAndNil (Retranslator); + inherited; +end; + +{ THook } + +constructor THook.Create(OldProcedure, NewProcedure: pointer; FollowJump:boolean=false); +{ Idea and original code from Igor Siticov } +{ Modified by Jacques Garcia Vazquez and Lars Dybdahl } +begin + {$ifndef CPU386} + 'This procedure only works on Intel i386 compatible processors.' + {$endif} + + oldproc:=OldProcedure; + newproc:=NewProcedure; + + Reset (FollowJump); +end; + +destructor THook.Destroy; +begin + Shutdown; + inherited; +end; + +procedure THook.Disable; +begin + Assert (PatchPosition<>nil,'Patch position in THook was nil when Disable was called'); + PatchPosition[0]:=Original[0]; + PatchPosition[1]:=Original[1]; + PatchPosition[2]:=Original[2]; + PatchPosition[3]:=Original[3]; + PatchPosition[4]:=Original[4]; +end; + +procedure THook.Enable; +begin + Assert (PatchPosition<>nil,'Patch position in THook was nil when Enable was called'); + PatchPosition[0]:=Patch[0]; + PatchPosition[1]:=Patch[1]; + PatchPosition[2]:=Patch[2]; + PatchPosition[3]:=Patch[3]; + PatchPosition[4]:=Patch[4]; +end; + +procedure THook.Reset(FollowJump: boolean); +var + offset:integer; + {$ifdef LINUX} + p:pointer; + pagesize:integer; + {$endif} + {$ifdef MSWindows} + ov: cardinal; + {$endif} +begin + if PatchPosition<>nil then + Shutdown; + + patchPosition := OldProc; + if FollowJump and (Word(OldProc^) = $25FF) then begin + // This finds the correct procedure if a virtual jump has been inserted + // at the procedure address + Inc(Integer(patchPosition), 2); // skip the jump + patchPosition := pChar(Pointer(pointer(patchPosition)^)^); + end; + offset:=integer(NewProc)-integer(pointer(patchPosition))-5; + + Patch[0] := char($E9); + Patch[1] := char(offset and 255); + Patch[2] := char((offset shr 8) and 255); + Patch[3] := char((offset shr 16) and 255); + Patch[4] := char((offset shr 24) and 255); + + Original[0]:=PatchPosition[0]; + Original[1]:=PatchPosition[1]; + Original[2]:=PatchPosition[2]; + Original[3]:=PatchPosition[3]; + Original[4]:=PatchPosition[4]; + + {$ifdef MSWINDOWS} + if not VirtualProtect(Pointer(PatchPosition), 5, PAGE_EXECUTE_READWRITE, @ov) then + RaiseLastOSError; + {$endif} + {$ifdef LINUX} + pageSize:=sysconf (_SC_PAGE_SIZE); + p:=pointer(PatchPosition); + p:=pointer((integer(p) + PAGESIZE-1) and not (PAGESIZE-1) - pageSize); + if mprotect (p, pageSize, PROT_READ + PROT_WRITE + PROT_EXEC) <> 0 then + RaiseLastOSError; + {$endif} +end; + +procedure THook.Shutdown; +begin + Disable; + PatchPosition:=nil; +end; + +procedure HookIntoResourceStrings (enabled:boolean=true; SupportPackages:boolean=false); +begin + HookLoadResString.Reset (SupportPackages); + HookLoadStr.Reset (SupportPackages); + HookFmtLoadStr.Reset (SupportPackages); + if enabled then begin + HookLoadResString.Enable; + HookLoadStr.Enable; + HookFmtLoadStr.Enable; + end; +end; + +{ TMoFile } + +function TMoFile.autoswap32(i: cardinal): cardinal; +var + cnv1, cnv2: + record + case integer of + 0: (arr: array[0..3] of byte); + 1: (int: cardinal); + end; +begin + if doswap then begin + cnv1.int := i; + cnv2.arr[0] := cnv1.arr[3]; + cnv2.arr[1] := cnv1.arr[2]; + cnv2.arr[2] := cnv1.arr[1]; + cnv2.arr[3] := cnv1.arr[0]; + Result := cnv2.int; + end else + Result := i; +end; + +function TMoFile.CardinalInMem(baseptr: PChar; Offset: Cardinal): Cardinal; +var pc:^Cardinal; +begin + inc (baseptr,offset); + pc:=Pointer(baseptr); + Result:=pc^; + if doswap then + autoswap32(Result); +end; + +constructor TMoFile.Create(filename: string; Offset,Size:int64); +var + i:cardinal; + nn:integer; + {$ifdef linux} + mofile:TFileStream; + {$endif} +begin + if sizeof(i) <> 4 then + raise EGGProgrammingError.Create('TDomain in gnugettext is written for an architecture that has 32 bit integers.'); + + {$ifdef mswindows} + // Map the mo file into memory and let the operating system decide how to cache + mo:=createfile (PChar(filename),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0); + if mo=INVALID_HANDLE_VALUE then + raise EGGIOError.Create ('Cannot open file '+filename); + momapping:=CreateFileMapping (mo, nil, PAGE_READONLY, 0, 0, nil); + if momapping=0 then + raise EGGIOError.Create ('Cannot create memory map on file '+filename); + momemoryHandle:=MapViewOfFile (momapping,FILE_MAP_READ,0,0,0); + if momemoryHandle=nil then begin + raise EGGIOError.Create ('Cannot map file '+filename+' into memory. Reason: '+GetLastWinError); + end; + momemory:=momemoryHandle+offset; + {$endif} + {$ifdef linux} + // Read the whole file into memory + mofile:=TFileStream.Create (filename, fmOpenRead or fmShareDenyNone); + try + if size=0 then + size:=mofile.Size; + Getmem (momemoryHandle,size); + momemory:=momemoryHandle; + mofile.Seek(offset,soFromBeginning); + mofile.ReadBuffer(momemory^,size); + finally + FreeAndNil (mofile); + end; + {$endif} + + // Check the magic number + doswap:=False; + i:=CardinalInMem(momemory,0); + if (i <> $950412DE) and (i <> $DE120495) then + EGGIOError.Create('This file is not a valid GNU gettext mo file: ' + filename); + doswap := (i = $DE120495); + + + // Find the positions in the file according to the file format spec + CardinalInMem(momemory,4); // Read the version number, but don't use it for anything. + N:=CardinalInMem(momemory,8); // Get string count + O:=CardinalInMem(momemory,12); // Get offset of original strings + T:=CardinalInMem(momemory,16); // Get offset of translated strings + + // Calculate start conditions for a binary search + nn := N; + startindex := 1; + while nn <> 0 do begin + nn := nn shr 1; + startindex := startindex shl 1; + end; + startindex := startindex shr 1; + startstep := startindex shr 1; +end; + +destructor TMoFile.Destroy; +begin + {$ifdef mswindows} + UnMapViewOfFile (momemoryHandle); + CloseHandle (momapping); + CloseHandle (mo); + {$endif} + {$ifdef linux} + FreeMem (momemoryHandle); + {$endif} + inherited; +end; + +function TMoFile.gettext(const msgid: ansistring;var found:boolean): ansistring; +var + i, step: cardinal; + offset, pos: cardinal; + CompareResult:integer; + msgidptr,a,b:PChar; + abidx:integer; + size, msgidsize:integer; +begin + found:=false; + msgidptr:=PChar(msgid); + msgidsize:=length(msgid); + + // Do binary search + i:=startindex; + step:=startstep; + while true do begin + // Get string for index i + pos:=O+8*(i-1); + offset:=CardinalInMem (momemory,pos+4); + size:=CardinalInMem (momemory,pos); + a:=msgidptr; + b:=momemory+offset; + abidx:=size; + if msgidsize0 do begin + CompareResult:=integer(byte(a^))-integer(byte(b^)); + if CompareResult<>0 then + break; + dec (abidx); + inc (a); + inc (b); + end; + if CompareResult=0 then + CompareResult:=msgidsize-size; + if CompareResult=0 then begin // msgid=s + // Found the msgid + pos:=T+8*(i-1); + offset:=CardinalInMem (momemory,pos+4); + size:=CardinalInMem (momemory,pos); + SetString (Result,momemory+offset,size); + found:=True; + break; + end; + if step=0 then begin + // Not found + Result:=msgid; + break; + end; + if CompareResult<0 then begin // msgids + i := i + step; + if i > N then + i := N; + step := step shr 1; + end; + end; +end; + +initialization + {$ifdef DXGETTEXTDEBUG} + {$ifdef MSWINDOWS} + MessageBox (0,'gnugettext.pas debugging is enabled. Turn it off before releasing this piece of software.','Information',MB_OK); + {$endif} + {$ifdef LINUX} + writeln (stderr,'gnugettext.pas debugging is enabled. Turn it off before releasing this piece of software.'); + {$endif} + {$endif} + if IsLibrary then begin + // Get DLL/shared object filename + SetLength (ExecutableFilename,300); + {$ifdef MSWINDOWS} + SetLength (ExecutableFilename,GetModuleFileName(HInstance, PChar(ExecutableFilename), length(ExecutableFilename))); + {$else} + // This line has not been tested on Linux, yet, but should work. + SetLength (ExecutableFilename,GetModuleFileName(0, PChar(ExecutableFilename), length(ExecutableFilename))); + {$endif} + end else + ExecutableFilename:=Paramstr(0); + FileLocator:=TFileLocator.Create; + FileLocator.Analyze; + ResourceStringDomainList:=TStringList.Create; + ResourceStringDomainList.Add(DefaultTextDomain); + ResourceStringDomainListCS:=TMultiReadExclusiveWriteSynchronizer.Create; + DefaultInstance:=TGnuGettextInstance.Create; + {$ifdef MSWINDOWS} + Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT); + {$endif} + + // replace Borlands LoadResString with gettext enabled version: + HookLoadResString:=THook.Create (@system.LoadResString, @LoadResStringA); + HookLoadStr:=THook.Create (@sysutils.LoadStr, @SysUtilsLoadStr); + HookFmtLoadStr:=THook.Create (@sysutils.FmtLoadStr, @SysUtilsFmtLoadStr); + HookIntoResourceStrings (AutoCreateHooks,false); + +finalization + FreeAndNil (DefaultInstance); + FreeAndNil (ResourceStringDomainListCS); + FreeAndNil (ResourceStringDomainList); + FreeAndNil (HookFmtLoadStr); + FreeAndNil (HookLoadStr); + FreeAndNil (HookLoadResString); + FreeAndNil (FileLocator); + +end. + diff --git a/win32/gui-2/gnugettextD4.pas b/win32/gui-2/gnugettextD4.pas new file mode 100644 index 000000000..f11c49555 --- /dev/null +++ b/win32/gui-2/gnugettextD4.pas @@ -0,0 +1,290 @@ +unit gnugettextD4; +(* File version: $Date: 2005/12/06 00:25:47 $ *) +(* Revision: $Revision: 1.3 $ *) +// Delphi 5 optimized interface for gnugettext.pas +// This unit must only be used on Delphi 5. When you upgrade to Delphi 6 or +// later, you should remove this unit and replace all reference to gnugettextD5 +// with refernces to gnugettext. + +interface + +uses + Classes, TypInfo; + +// Ansistring versions of the api +function _(const szMsgId: string): string; +function gettext(const szMsgId: string): string; +function dgettext(const szDomain: string; const szMsgId: string): string; +procedure TranslateComponent(AnObject: TComponent); + +//***************************************************************************** +// Don't use anything in the interface below this line. +// It only contains code or gnugettext.pas to make it compile with Delphi 5. + +type + UTF8String = AnsiString; + +const + PathDelim='\'; + sLineBreak=#13#10; + +function GetEnvironmentVariable(const VarName: string): string; +function DirectoryExists(const Name:string):boolean; +function IncludeTrailingPathDelimiter(s: string): string; +function ExcludeTrailingPathDelimiter(s: string): string; +procedure RaiseLastOSError; +function StrToFloatDef(const S:String;Default:Extended):Extended; +function Utf8Decode(const S: UTF8String): WideString; +function Utf8Encode(const WS: WideString): UTF8String; + +// for delphi 4 + +procedure FreeAndNil(var P); +function IncludeTrailingBackSlash(const Path: string): string; +function ExcludeTrailingBackslash(const Path: string): string; + +implementation + +uses + filectrl, Windows, SysUtils, + gnugettext; + +function GetEnvironmentVariable(const VarName: string): string; +var Size: Integer; +begin + Size := Windows.GetEnvironmentVariable(PChar(VarName), nil, 0); + SetLength(Result, Size - 1); + Windows.GetEnvironmentVariable(PChar(VarName), PChar(Result), Size); +end; + +function DirectoryExists(const Name:string):boolean; +begin + Result := FileCtrl.DirectoryExists(Name); +end; + +function IncludeTrailingPathDelimiter(s: string): string; +begin + Result := IncludeTrailingBackslash(s); +end; + +function ExcludeTrailingPathDelimiter(s: string): string; +begin + Result := ExcludeTrailingBackslash(s); +end; + +procedure RaiseLastOSError; +begin + RaiseLastWin32Error; +end; + +function StrToFloatDef(const S:String;Default:Extended):Extended; +begin + if not TextToFloat(PChar(S), Result, fvExtended) then + Result := Default; +end; + +function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Cardinal; +begin + Result := 0; + if Source = nil then + Exit; + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceChars) and (count < MaxDestBytes) do begin + c := Cardinal(Source[i]); + Inc(i); + if c <= $7F then begin + Dest[count] := Char(c); + Inc(count); + end else + if c > $7FF then begin + if count + 3 > MaxDestBytes then + break; + Dest[count] := Char($E0 or (c shr 12)); + Dest[count + 1] := Char($80 or ((c shr 6) and $3F)); + Dest[count + 2] := Char($80 or (c and $3F)); + Inc(count, 3); + end else // $7F < Source[i] <= $7FF + begin + if count + 2 > MaxDestBytes then + break; + Dest[count] := Char($C0 or (c shr 6)); + Dest[count + 1] := Char($80 or (c and $3F)); + Inc(count, 2); + end; + end; + if count >= MaxDestBytes then + count := MaxDestBytes - 1; + Dest[count] := #0; + end else begin + while i < SourceChars do begin + c := Integer(Source[i]); + Inc(i); + if c > $7F then begin + if c > $7FF then + Inc(count); + Inc(count); + end; + Inc(count); + end; + end; + Result := count + 1; // convert zero based index to byte count +end; + +function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Byte; + wc: Cardinal; +begin + if Source = nil then begin + Result := 0; + Exit; + end; + Result := Cardinal(-1); + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceBytes) and (count < MaxDestChars) do begin + wc := Cardinal(Source[i]); + Inc(i); + if (wc and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := wc and $3F; + if (wc and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := (wc shl 6) or (c and $3F); + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + + Dest[count] := WideChar((wc shl 6) or (c and $3F)); + end else + Dest[count] := WideChar(wc); + Inc(count); + end; + if count >= MaxDestChars then + count := MaxDestChars - 1; + Dest[count] := #0; + end else begin + while (i < SourceBytes) do begin + c := Byte(Source[i]); + Inc(i); + if (c and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + c := c and $3F; + if (c and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + end; + Inc(count); + end; + end; + Result := count + 1; +end; + +function Utf8Decode(const S: UTF8String): WideString; +var + L: Integer; + Temp: WideString; +begin + Result := ''; + if S = '' then + Exit; + SetLength(Temp, Length(S)); + + L := Utf8ToUnicode(PWideChar(Temp), Length(Temp) + 1, PChar(S), Length(S)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function Utf8Encode(const WS: WideString): UTF8String; +var + L: Integer; + Temp: UTF8String; +begin + Result := ''; + if WS = '' then + Exit; + SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator + + L := UnicodeToUtf8(PChar(Temp), Length(Temp) + 1, PWideChar(WS), Length(WS)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function _(const szMsgId: string): string; +begin + Result:=gettext(szMsgid); +end; + +function gettext(const szMsgId: string): string; +begin + Result:=string(DefaultInstance.gettext(DefaultInstance.ansi2wide(szMsgId))); +end; + +function dgettext(const szDomain: string; const szMsgId: string): string; +begin + Result:=string(DefaultInstance.dgettext(szDomain,DefaultInstance.ansi2wide(szMsgId))); +end; + +procedure TranslateComponent(AnObject: TComponent); +begin + gnugettext.TranslateComponent(AnObject); +end; + +// for delphi 4 + +procedure FreeAndNil(var P); +begin + TObject(P).Free; + Pointer(P) := NIL; +end; + +function IncludeTrailingBackSlash(const Path: string): string; +begin + if (Path <> '') and + not(Path[Length(Path)] in [':', '\']) then + Result := Path + '\' + else + Result := Path; +end; + +function ExcludeTrailingBackslash(const Path: string): string; +var + Len: Integer; +begin + Len := Length(Path); + while (Len > 0) and (Path[Len] in ['/', '\']) do Dec(Len); + SetString(Result, PChar(Path), Len); +end; + +end. diff --git a/win32/gui-2/gnugettextD5.pas b/win32/gui-2/gnugettextD5.pas new file mode 100644 index 000000000..8a586060d --- /dev/null +++ b/win32/gui-2/gnugettextD5.pas @@ -0,0 +1,265 @@ +unit gnugettextD5; +// Information about this file: +// $LastChangedDate: 2005-04-04 19:40:57 +0200 (Mon, 04 Apr 2005) $ +// $LastChangedRevision: 60 $ +// $HeadURL: svn://svn.berlios.de/dxgettext/trunk/dxgettext/sample/gnugettextD5.pas $ + +// Delphi 5 optimized interface for gnugettext.pas +// This unit must only be used on Delphi 5. When you upgrade to Delphi 6 or +// later, you should remove this unit and replace all reference to gnugettextD5 +// with refernces to gnugettext. + +interface + +uses + Classes; + +// Ansistring versions of the api +function _(const szMsgId: string): string; +function gettext(const szMsgId: string): string; +function dgettext(const szDomain: string; const szMsgId: string): string; +procedure TranslateComponent(AnObject: TComponent); + + + +//***************************************************************************** +// Don't use anything in the interface below this line. +// It only contains code or gnugettext.pas to make it compile with Delphi 5. + +type + UTF8String = AnsiString; + +const + PathDelim='\'; + sLineBreak=#13#10; + +function GetEnvironmentVariable(const VarName: string): string; +function DirectoryExists(const Name:string):boolean; +function IncludeTrailingPathDelimiter(s: string): string; +function ExcludeTrailingPathDelimiter(s: string): string; +procedure RaiseLastOSError; +function StrToFloatDef(const S:String;Default:Extended):Extended; +function Utf8Decode(const S: UTF8String): WideString; +function Utf8Encode(const WS: WideString): UTF8String; + + + +implementation + +uses + filectrl, Windows, SysUtils, + gnugettext; + +function GetEnvironmentVariable(const VarName: string): string; +var Size: Integer; +begin + Size := Windows.GetEnvironmentVariable(PChar(VarName), nil, 0); + SetLength(Result, Size - 1); + Windows.GetEnvironmentVariable(PChar(VarName), PChar(Result), Size); +end; + +function DirectoryExists(const Name:string):boolean; +begin + Result := FileCtrl.DirectoryExists(Name); +end; + +function IncludeTrailingPathDelimiter(s: string): string; +begin + Result := IncludeTrailingBackslash(s); +end; + +function ExcludeTrailingPathDelimiter(s: string): string; +begin + Result := ExcludeTrailingBackslash(s); +end; + +procedure RaiseLastOSError; +begin + RaiseLastWin32Error; +end; + +function StrToFloatDef(const S:String;Default:Extended):Extended; +begin + if not TextToFloat(PChar(S), Result, fvExtended) then + Result := Default; +end; + +function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Cardinal; +begin + Result := 0; + if Source = nil then + Exit; + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceChars) and (count < MaxDestBytes) do begin + c := Cardinal(Source[i]); + Inc(i); + if c <= $7F then begin + Dest[count] := Char(c); + Inc(count); + end else + if c > $7FF then begin + if count + 3 > MaxDestBytes then + break; + Dest[count] := Char($E0 or (c shr 12)); + Dest[count + 1] := Char($80 or ((c shr 6) and $3F)); + Dest[count + 2] := Char($80 or (c and $3F)); + Inc(count, 3); + end else // $7F < Source[i] <= $7FF + begin + if count + 2 > MaxDestBytes then + break; + Dest[count] := Char($C0 or (c shr 6)); + Dest[count + 1] := Char($80 or (c and $3F)); + Inc(count, 2); + end; + end; + if count >= MaxDestBytes then + count := MaxDestBytes - 1; + Dest[count] := #0; + end else begin + while i < SourceChars do begin + c := Integer(Source[i]); + Inc(i); + if c > $7F then begin + if c > $7FF then + Inc(count); + Inc(count); + end; + Inc(count); + end; + end; + Result := count + 1; // convert zero based index to byte count +end; + +function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal; +var + i, count: Cardinal; + c: Byte; + wc: Cardinal; +begin + if Source = nil then begin + Result := 0; + Exit; + end; + Result := Cardinal(-1); + count := 0; + i := 0; + if Dest <> nil then begin + while (i < SourceBytes) and (count < MaxDestChars) do begin + wc := Cardinal(Source[i]); + Inc(i); + if (wc and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := wc and $3F; + if (wc and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + wc := (wc shl 6) or (c and $3F); + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + + Dest[count] := WideChar((wc shl 6) or (c and $3F)); + end else + Dest[count] := WideChar(wc); + Inc(count); + end; + if count >= MaxDestChars then + count := MaxDestChars - 1; + Dest[count] := #0; + end else begin + while (i < SourceBytes) do begin + c := Byte(Source[i]); + Inc(i); + if (c and $80) <> 0 then begin + if i >= SourceBytes then + Exit; // incomplete multibyte char + c := c and $3F; + if (c and $20) <> 0 then begin + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte or out of range char + if i >= SourceBytes then + Exit; // incomplete multibyte char + end; + c := Byte(Source[i]); + Inc(i); + if (c and $C0) <> $80 then + Exit; // malformed trail byte + end; + Inc(count); + end; + end; + Result := count + 1; +end; + +function Utf8Decode(const S: UTF8String): WideString; +var + L: Integer; + Temp: WideString; +begin + Result := ''; + if S = '' then + Exit; + SetLength(Temp, Length(S)); + + L := Utf8ToUnicode(PWideChar(Temp), Length(Temp) + 1, PChar(S), Length(S)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function Utf8Encode(const WS: WideString): UTF8String; +var + L: Integer; + Temp: UTF8String; +begin + Result := ''; + if WS = '' then + Exit; + SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator + + L := UnicodeToUtf8(PChar(Temp), Length(Temp) + 1, PWideChar(WS), Length(WS)); + if L > 0 then + SetLength(Temp, L - 1) + else + Temp := ''; + Result := Temp; +end; + +function _(const szMsgId: string): string; +begin + Result:=gettext(szMsgid); +end; + +function gettext(const szMsgId: string): string; +begin + Result:=string(DefaultInstance.gettext(DefaultInstance.ansi2wideDTCP(szMsgId))); +end; + +function dgettext(const szDomain: string; const szMsgId: string): string; +begin + Result:=string(DefaultInstance.dgettext(szDomain,DefaultInstance.ansi2wideDTCP(szMsgId))); +end; + +procedure TranslateComponent(AnObject: TComponent); +begin + gnugettext.TranslateComponent(AnObject); +end; + +end. diff --git a/win32/gui-2/gnugettextDx.pas b/win32/gui-2/gnugettextDx.pas new file mode 100644 index 000000000..af1c713b8 --- /dev/null +++ b/win32/gui-2/gnugettextDx.pas @@ -0,0 +1,72 @@ +unit gnugettextDx; + +interface + +uses + Classes, TypInfo, +{$IFDEF VER120} + gnugettextD4; +{$ELSE} +{$IFDEF VER130} + gnugettextD5; +{$ELSE} + gnugettext; +{$ENDIF} +{$ENDIF} + +function _(const szMsgId: string): string; +function gettext(const szMsgId: string): string; +function dgettext(const szDomain: string; const szMsgId: string): string; +procedure TranslateComponent(AnObject: TComponent); + +implementation + +function _(const szMsgId: string): string; +begin +{$IFDEF VER120} + Result := gnugettextD4._(szMsgId); +{$ELSE} +{$IFDEF VER130} + Result := gnugettextD5._(szMsgId); +{$ELSE} + Result := gnugettext._(szMsgId); +{$ENDIF}{$ENDIF} +end; + +function gettext(const szMsgId: string): string; +begin +{$IFDEF VER120} + Result := gnugettextD4.gettext(szMsgId); +{$ELSE} +{$IFDEF VER130} + Result := gnugettextD5.gettext(szMsgId); +{$ELSE} + Result := gnugettext.gettext(szMsgId); +{$ENDIF}{$ENDIF} +end; + +function dgettext(const szDomain: string; const szMsgId: string): string; +begin +{$IFDEF VER120} + Result := gnugettextD4.dgettext(szDomain, szMsgId); +{$ELSE} +{$IFDEF VER130} + Result := gnugettextD5.dgettext(szDomain, szMsgId); +{$ELSE} + Result := gnugettext.dgettext(szDomain, szMsgId); +{$ENDIF}{$ENDIF} +end; + +procedure TranslateComponent(AnObject: TComponent); +begin +{$IFDEF VER120} + gnugettextD4.TranslateComponent(AnObject); +{$ELSE} +{$IFDEF VER130} + gnugettextD5.TranslateComponent(AnObject); +{$ELSE} + gnugettext.TranslateComponent(AnObject); +{$ENDIF}{$ENDIF} +end; + +end. diff --git a/win32/gui-2/gpsbabel.iss b/win32/gui-2/gpsbabel.iss new file mode 100644 index 000000000..c86cf33d4 --- /dev/null +++ b/win32/gui-2/gpsbabel.iss @@ -0,0 +1,120 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define Version "1.3.2" +#define Release "" + +[Setup] +AppName=GPSBabel +AppVerName=GPSBabel-{#Version}{#Release} +RestartIfNeededByRun=false +DefaultDirName={pf}\GPSBabel-{#Version} +ShowLanguageDialog=auto +OutputDir=C:\TEMP +SourceDir=.\ +DefaultGroupName=GPSBabel +AlwaysUsePersonalGroup=true +UserInfoPage=false +EnableDirDoesntExistWarning=true +VersionInfoVersion={#Version} +VersionInfoCompany=GPSBabel makers +AllowRootDirectory=true +AlwaysShowGroupOnReadyPage=true +InternalCompressLevel=fast +WindowVisible=false +SetupIconFile=GPSBabelGUI.ico +DisableFinishedPage=false +AppVersion={#Version}{#Release} +UninstallDisplayIcon={app}\GPSBabelGUI.exe +UninstallDisplayName=GPSBabel {#Version} +AppPublisherURL=http://www.gpsbabel.org +AppUpdatesURL=http://sourceforge.net/project/showfiles.php?group_id=58972 +DisableStartupPrompt=true +AppID={{E25E9E85-2244-4AB0-B00D-7F44C6E9F635} +AppMutex=GPSBabelGUI_mutex +OutputBaseFilename=iGPSBabel-{#Version}{#Release} +UsePreviousAppDir=false + +[Tasks] +Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked +Name: quicklaunchicon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked + +[Files] +Source: GPSBabelGUI.exe; DestDir: {app}; Flags: replacesameversion +Source: README.gui; DestDir: {app} +Source: ..\..\mingw\libexpat.dll; DestDir: {app} +; Source: ..\..\mingw\sqlite3.dll; DestDir: {app} +Source: ..\..\gpsbabel.exe; DestDir: {app}; Flags: comparetimestamp ignoreversion; Languages: +Source: ..\..\gpsbabel.html; DestDir: {app}; Tasks: ; Languages: +Source: ..\..\COPYING; DestDir: {app} +Source: ..\..\README.contrib; DestDir: {app} +Source: ..\..\README.igc; DestDir: {app} +Source: ..\..\README.magnav; DestDir: {app} +Source: ..\..\README.mapconverter; DestDir: {app} +Source: ..\..\README.psp; DestDir: {app} +Source: ..\..\AUTHORS; DestDir: {app}; Tasks: ; Languages: +Source: ..\..\CHANGELOG; DestDir: {app} + +[Dirs] +Name: {app} + +[Languages] +Name: en; MessagesFile: compiler:Default.isl +Name: de; MessagesFile: compiler:Languages\German.isl +Name: fr; MessagesFile: compiler:Languages\French.isl + +[Icons] +Name: {group}\GPSBabelGUI; Filename: {app}\GPSBabelGUI.exe; WorkingDir: {app}; IconFilename: {app}\GPSBabelGUI.exe; IconIndex: 0; Flags: useapppaths +Name: {group}\{cm:UninstallProgram, GPSBabel}; Filename: {uninstallexe} +Name: {userdesktop}\GPSBabelGUI; Filename: {app}\GPSBabelGUI.exe; WorkingDir: {app}; Tasks: desktopicon; IconIndex: 0 +Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\GPSBabelGUI; Filename: {app}\GPSBabelGUI.exe; Tasks: quicklaunchicon; WorkingDir: {app}; IconFilename: {app}\GPSBabelGUI.exe; IconIndex: 0 + +[Run] +Filename: {app}\GPSBabelGUI.exe; WorkingDir: {app}; Flags: postinstall unchecked skipifsilent; Description: {cm:LaunchProgram,GPSBabelBUI} + +[Code] +var + GPSBabelPathRead: Boolean; + GPSBabelPath: string; + +function InitializeSetup(): Boolean; +begin + GPSBabelPathRead := False; + Result := True; +end; + +function GetGPSBabelPath(): String; +var + GPSBabelPathKeyName, GPSBabelPathValueName: String; +begin + if not GPSBabelPathRead then + begin + GPSBabelPathRead := True; + GPSBabelPathKeyName := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{E25E9E85-2244-4AB0-B00D-7F44C6E9F635}_is1'; + GPSBabelPathValueName := 'Inno Setup: App Path'; + if not(RegQueryStringValue(HKLM, GPSBabelPathKeyName, GPSBabelPathValueName, GPSBabelPath)) then + begin + Result := ''; + GPSBabelPath := Result; + end; + end; + Result := GPSBabelPath; +end; + +function NextButtonClick(CurPageID: Integer): Boolean; +var + s: string; +begin +// PageID's (wpSelectDir, wpSelectProgramGroup, wpReady) + Result := True; + if (CurPageID = wpSelectDir) then + begin + s := GetGPSBabelPath(); + if (s <> '') and (CompareText(s, WizardDirValue()) = 0) then + begin + Result := ( + MsgBox('GPSBabel seems to be installed in this path!' + #13#13 + + 'Overwrite previous installation?', mbConfirmation, mb_YesNo) = mrYes); + end; + end; +end; diff --git a/win32/gui-2/gpsbabel.po b/win32/gui-2/gpsbabel.po new file mode 100644 index 000000000..b462a6cd9 --- /dev/null +++ b/win32/gui-2/gpsbabel.po @@ -0,0 +1,387 @@ +msgid "" +msgstr "" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "" + +msgid "(USR input) Break segments into separate tracks" +msgstr "" + +msgid "(USR output) Merge into one segmented track" +msgstr "" + +msgid "Ad-hoc closed icon name" +msgstr "" + +msgid "Ad-hoc open icon name" +msgstr "" + +msgid "Allow whitespace synth. shortnames" +msgstr "" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "" + +msgid "Append icon_descr to description" +msgstr "" + +msgid "Base URL for link tag in output" +msgstr "" + +msgid "Basename prepended to URL on output" +msgstr "" + +msgid "Category name (Cache)" +msgstr "" + +msgid "Category number to use for written waypoints" +msgstr "" + +msgid "Color for lines or mapnotes" +msgstr "" + +msgid "Command unit to power itself down" +msgstr "" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "" + +msgid "Create waypoints from geocache log entries" +msgstr "" + +msgid "Database name" +msgstr "" + +msgid "Database name (filename)" +msgstr "" + +msgid "Datum (default=NAD27)" +msgstr "" + +msgid "Days after which points are considered old" +msgstr "" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "" + +msgid "Default category on output (1..16)" +msgstr "" + +msgid "Default icon name" +msgstr "" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "" + +msgid "Delete all waypoints" +msgstr "" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "" + +msgid "Do not add geocache data to description" +msgstr "" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "" + +msgid "Encrypt hints using ROT13" +msgstr "" + +msgid "Encrypt hints with ROT13" +msgstr "" + +msgid "Erase device data after download" +msgstr "" + +msgid "Export linestrings for tracks and routes" +msgstr "" + +msgid "Export placemarks for tracks and routes" +msgstr "" + +msgid "Full path to XCSV style file" +msgstr "" + +msgid "Generate file with lat/lon for centering map" +msgstr "" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "" + +msgid "GPS datum (def. WGS 84)" +msgstr "" + +msgid "Height in pixels of map" +msgstr "" + +msgid "Ignore event marker icons" +msgstr "" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "" + +msgid "Include groundspeak logs if present" +msgstr "" + +msgid "Include only via stations in route" +msgstr "" + +msgid "Include short name in bookmarks" +msgstr "" + +msgid "Index of name field in .dbf" +msgstr "" + +msgid "Index of route (if more the one in source)" +msgstr "" + +msgid "Index of route to write (if more the one in source)" +msgstr "" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "" + +msgid "Index of track (if more the one in source)" +msgstr "" + +msgid "Index of track to write (if more the one in source)" +msgstr "" + +msgid "Index of URL field in .dbf" +msgstr "" + +msgid "Infrastructure closed icon name" +msgstr "" + +msgid "Infrastructure open icon name" +msgstr "" + +msgid "Keep turns if simplify filter is used" +msgstr "" + +msgid "Length of generated shortnames" +msgstr "" + +msgid "Length of generated shortnames (default 16)" +msgstr "" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "" + +msgid "Make synth. shortnames unique" +msgstr "" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "" + +msgid "Margin for map. Degrees or percentage" +msgstr "" + +msgid "Marker type for new points" +msgstr "" + +msgid "Marker type for old points" +msgstr "" + +msgid "Marker type for unfound points" +msgstr "" + +msgid "Max length of waypoint name to write" +msgstr "" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "" + +msgid "Max shortname length when used with -s" +msgstr "" + +msgid "Max synthesized shortname length" +msgstr "" + +msgid "Merge output with existing file" +msgstr "" + +msgid "Name of the 'unassigned' category" +msgstr "" + +msgid "New name for the route" +msgstr "" + +msgid "No separator lines between waypoints" +msgstr "" + +msgid "No whitespace in generated shortnames" +msgstr "" + +msgid "Non-stealth encrypted icon name" +msgstr "" + +msgid "Non-stealth non-encrypted icon name" +msgstr "" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "" + +msgid "Omit Placer name" +msgstr "" + +msgid "Only read turns; skip all other points" +msgstr "" + +msgid "Path to HTML style sheet" +msgstr "" + +msgid "Precision of coordinates" +msgstr "" + +msgid "Radius for circles" +msgstr "" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "" + +msgid "Read control points as waypoint/route/none" +msgstr "" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "" + +msgid "Read/write GPGGA sentences" +msgstr "" + +msgid "Read/write GPGSA sentences" +msgstr "" + +msgid "Read/write GPRMC sentences" +msgstr "" + +msgid "Read/write GPVTG sentences" +msgstr "" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "" + +msgid "Return current position as a waypoint" +msgstr "" + +msgid "Road type changes" +msgstr "" + +msgid "Shortname is MAC address" +msgstr "" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "" + +msgid "Split input into separate files" +msgstr "" + +msgid "Split into multiple routes at turns" +msgstr "" + +msgid "Stealth encrypted icon name" +msgstr "" + +msgid "Stealth non-encrypted icon name" +msgstr "" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "" + +msgid "Suppress labels on generated pins" +msgstr "" + +msgid "Suppress retired geocaches" +msgstr "" + +msgid "Suppress separator lines between waypoints" +msgstr "" + +msgid "Suppress use of handshaking in name of speed" +msgstr "" + +msgid "Suppress whitespace in generated shortnames" +msgstr "" + +msgid "Symbol to use for point data" +msgstr "" + +msgid "Synthesize track times" +msgstr "" + +msgid "Target GPX version for output" +msgstr "" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "" + +msgid "The icon description is already the marker" +msgstr "" + +msgid "Type of .an1 file" +msgstr "" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "" + +msgid "UPPERCASE synth. shortnames" +msgstr "" + +msgid "Use depth values on output (default is ignore)" +msgstr "" + +msgid "Use proximity values on output (default is ignore)" +msgstr "" + +msgid "Use shortname instead of description" +msgstr "" + +msgid "Version of gdb file to generate (1,2)" +msgstr "" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "" + +msgid "Waypoint background color" +msgstr "" + +msgid "Waypoint foreground color" +msgstr "" + +msgid "Waypoint type" +msgstr "" + +msgid "Width in pixels of map" +msgstr "" + +msgid "Width of lines, in pixels" +msgstr "" + +msgid "Write timestamps with offset x to UTC time" +msgstr "" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "" + +msgid "Zoom level to reduce points" +msgstr "" + diff --git a/win32/gui-2/ignore.po b/win32/gui-2/ignore.po new file mode 100644 index 000000000..bf00e1699 --- /dev/null +++ b/win32/gui-2/ignore.po @@ -0,0 +1,297 @@ +# Doesn't have any letters +#. frmMain..MainMenu1..mnuFile..N5..Caption +#: main.dfm:1495 +#. frmMain..MainMenu1..mnuFile..N3..Caption +#: main.dfm:1501 +#. frmMain..MainMenu1..mnuOptions..N2..Caption +#: main.dfm:1525 +#. frmMain..MainMenu1..mnuOptions..N4..Caption +#: main.dfm:1537 +#. frmMain..MainMenu1..mnuHelp..N1..Caption +#: main.dfm:1566 +msgid "-" +msgstr "" + +# Doesn't have any letters +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:33 +msgid "+/-" +msgstr "" + +# Doesn't have any letters +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Text +#: filter.dfm:344 +msgid "50 " +msgstr "" + +#. frmFilter..gbTracks..edTrackTitle..Text +#: filter.dfm:88 +msgid "ACTIVE LOG # %Y%m%d" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:153 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:368 +msgid "ASCII" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:184 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:399 +msgid "COM1" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:185 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:400 +msgid "COM2" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:186 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:401 +msgid "COM3" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:187 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:402 +msgid "COM4" +msgstr "" + +#. frmMain..ActionList1..acDebugCreatePo..Caption +#: main.dfm:1459 +msgid "Create options.po" +msgstr "" + +#. frmMain..ActionList1..acDebugCreatePo..Category +#: main.dfm:1458 +#. frmMain..MainMenu1..mnuDebug..Caption +#: main.dfm:1546 +msgid "Debug" +msgstr "" + +# Seems like a Font.Name extract +#. frmMain..memoOutput..Font.Name +#: main.dfm:678 +msgid "Fixedsys" +msgstr "" + +# Doesn't look like text +#. frmMain..Caption +#: main.dfm:6 +#. Programmer's name for it: SGPSBabelTitle +#: common.pas:32 +msgid "GPSBabelGUI-2" +msgstr "" + +# Doesn't look like text +#. frmAbout..pnClient..Panel1..StaticText1..Caption +#: about.dfm:94 +msgid "GPSBabelGUI-2:" +msgstr "" + +#. Programmer's name for it: SGPSBabelURL +#: common.pas:31 +msgid "http://www.gpsbabel.org" +msgstr "" + +#. frmMain..stbMain........Text +#: main.dfm:703 +msgid "http://www.gpsbabel.org (http://sourceforge.net/projects/gpsbabel)" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:156 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:371 +msgid "ISO-8859-1" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:165 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:380 +msgid "ISO-8859-10" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:166 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:381 +msgid "ISO-8859-13" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:167 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:382 +msgid "ISO-8859-14" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:168 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:383 +msgid "ISO-8859-15" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:157 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:372 +msgid "ISO-8859-2" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:158 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:373 +msgid "ISO-8859-3" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:159 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:374 +msgid "ISO-8859-4" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:160 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:375 +msgid "ISO-8859-5" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:161 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:376 +msgid "ISO-8859-6" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:162 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:377 +msgid "ISO-8859-7" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:163 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:378 +msgid "ISO-8859-8" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:164 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:379 +msgid "ISO-8859-9" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:169 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:384 +msgid "KOI-8" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:170 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:385 +msgid "MACROMAN" +msgstr "" + +msgid "MAC-ROMAN" +msgstr "" + +# Seems like a Font.Name extract +#. frmAbout..Font.Name +#: about.dfm:12 +#. frmAbout..pnClient..pnCenter..lbURL..Font.Name +#: about.dfm:102 +#. frmAbout..pnClient..pnCenter..lbSFURL..Font.Name +#: about.dfm:133 +#. frmAbout..pnClient..pnCenter..stLicense..Font.Name +#: about.dfm:168 +#. frmFilter..Font.Name +#: filter.dfm:13 +#. frmMain..Font.Name +#: main.dfm:13 +#. frmMain..pnBottom..lbWhat..Font.Name +#: main.dfm:427 +#. frmMain..stbMain..Font.Name +#: main.dfm:693 +#. frmOptions..Font.Name +#: options.dfm:14 +#. frmOptions..pnOptions..Font.Name +#: options.dfm:68 +#. frmOptions..pnOptions..mmWarning..Font.Name +#: options.dfm:85 +#. frmReadme..Font.Name +#: readme.dfm:11 +#. frmSelect..Font.Name +#: select.dfm:12 +#. frmSelect..pnTop..lbSelect..Font.Name +#: select.dfm:36 +msgid "MS Sans Serif" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:154 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:369 +msgid "MS-ANSI" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbSFURL..Caption +#: about.dfm:128 +msgid "SourceForge.net" +msgstr "" + +# +msgid "US-ASCII" +msgstr "" + +#. frmMain..pnTop..gbInput..cbInputDevice....Items.Strings +#: main.dfm:183 +#. frmMain..pnTop..gbOutput..cbOutputDevice....Items.Strings +#: main.dfm:398 +msgid "USB" +msgstr "" + +# Doesn't look like text +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#: main.dfm:155 +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:370 +msgid "UTF-8" +msgstr "" + diff --git a/win32/gui-2/locale/de/LC_MESSAGES/default.po b/win32/gui-2/locale/de/LC_MESSAGES/default.po new file mode 100644 index 000000000..bd203e9ae --- /dev/null +++ b/win32/gui-2/locale/de/LC_MESSAGES/default.po @@ -0,0 +1,903 @@ +# +msgid "" +msgstr "" +"Project-Id-Version: GPSBabelGUI-2\n" +"POT-Creation-Date: 2005-08-12 14:50\n" +"PO-Revision-Date: 2006-11-01 20:12+0100\n" +"Last-Translator: Olaf Klein \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2\n" +"X-Poedit-Language: German\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "Über" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted on" +msgstr "Dieses Programm ist Bestandteil des Projektes \"GPSBabel\", zu finden auf" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "Version" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "Übersetzungen" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "www.gpsbabel.org" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "Mehr Info's unter" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line program" +msgstr "Das Windows-Fontend für \"gpsbabel.exe\"" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF CHARGE" +msgstr "DIESE SOFTWARE KANN UND DARF NUR KOSTENLOS WEITERGEGEBEN WERDEN" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "Eine neue Sprache hinzufügen" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "Filter" + +#. frmFilter..gbTracks..Caption +#. frmMain..pnBottom..cbTracks..Caption +#: filter.dfm:31 +#: main.dfm:581 +msgid "&Tracks" +msgstr "&Tracks" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +msgid "by" +msgstr "von" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "Tag(e)," + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "Stunde(n)," + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "Minute(n)," + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "Sekunde(n)" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "Titel für neu erstellte Tracks" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "Tite&l" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of trackpoint" +msgstr "Erzeuge mehrere Tracks abhängig vom Datum der Trackpunkte" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "&Splitten" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "Tracks um ein Zeitintervall verschieben " + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "Verschieben" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "beginne bei Zeitpunkt ..." + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "Beginnend am" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "bis zum" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate timestamps)" +msgstr "Alle Tracks zu einem einzigen zusammenfassen (doppelte Zeitstempel unzulässig)" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "&Packen (oder)" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "Fasse alle Tracks zu einem einzigen zusammen (doppelte Zeitstempel werden verworfen)" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "Zusammenführen" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "Verschiebe Beginn/Ende um Differenz zur lokalen Zeitzone" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "\"TZ\"" + +#. frmFilter..gbTracks..cbTrackFixes..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, 2D)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackFixes..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:315 +msgid "Synthesize course values" +msgstr "Generiere Kurs-Werte" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:316 +msgid "Course" +msgstr "Kurs" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:324 +msgid "Synthesize speed values" +msgstr "Generiere Geschwindigkeitswerte" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:325 +msgid "Speed" +msgstr "Geschwindigkeit" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:335 +msgid "&Routes && Tracks" +msgstr "&Routen && Tracks" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:343 +msgid "limit to" +msgstr "auf maximal" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:351 +msgid "Points" +msgstr "Punkte" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:358 +msgid "Simplify routes and tracks by limited number of points" +msgstr "Limitiert die Anzahl von Wegpunkten in Routen und Tracks" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:359 +msgid "Simplify" +msgstr "Vereinfachen" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:368 +msgid "Upper limit of points for routes and tracks" +msgstr "Maximale Anzahl an Punkten innerhalb von Routen und Tracks" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:390 +msgid "Reverse routes and tracks" +msgstr "Reihenfolge von Wegpunkten in Routen und Tracks umdrehen" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:391 +msgid "Reverse" +msgstr "Umdrehen" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:408 +msgid "OK" +msgstr "OK" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:444 +msgid "File based filters" +msgstr "Datei basierende Filter" + +#. frmFilter..gbWaypoints..Caption +#. frmMain..pnBottom..cbWaypoints..Caption +#: filter.dfm:473 +#: main.dfm:555 +msgid "&Waypoints" +msgstr "&Wegpunkte" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:482 +msgid "Latitude" +msgstr "Breitengrad" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:490 +msgid "Longitude" +msgstr "Längengrad" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:498 +msgid "Merge waypoints with duplicate locations" +msgstr "Fasse Wegpunkte mit gleichen Koordinaten zusammen" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:499 +msgid "locations" +msgstr "Koordinaten" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:508 +msgid "Merge waypoints with duplicate \"short name\"" +msgstr "Fasse Wegpunkte mit gleichem Namen zusammen" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:509 +msgid "\"short names\"" +msgstr "\"Kurznamen\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:518 +msgid "Merge waypoints separated by less then" +msgstr "Fasse alle Wegpunkte zusammen, die weniger als ... auseinander liegen" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:519 +msgid "Position" +msgstr "Position" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:547 +msgid "Sort waypoints by \"short name\" or by description" +msgstr "Sortiere Wegpunkte nach Name oder Beschreibung" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:548 +msgid "Sort" +msgstr "Sortieren" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:556 +msgid "Merge duplicate waypoints" +msgstr "Entferne doppelte Wegpunkte" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:557 +msgid "Duplicates" +msgstr "Duplikate" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:566 +msgid "Include points based on their proximity to central point" +msgstr "Übernehme nur Punkte mit Entfernung von maximal ... um Mittelpunkt ..." + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:567 +msgid "Radius" +msgstr "Radius" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:595 +msgid "Latitude of central point" +msgstr "Breitengrad (Latitude) des Mittelpunktes" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:605 +msgid "Longitude of central point" +msgstr "Längengrad (Longitude) des Mittelpunktes" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:617 +msgid "Transformation" +msgstr "Transformation" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:634 +msgid "Transform" +msgstr "Transformiere" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:643 +msgid "Delete source data after transformation" +msgstr "Lösche anschließend die internen Quelldaten" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:644 +msgid "Delete" +msgstr "Lösche" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:471 +#: main.pas:872 +msgid "Input" +msgstr "Eingabe" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "Die zu lesende Datei auswählen" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:68 +#: main.dfm:229 +#: main.dfm:1418 +#: main.dfm:1423 +#: main.dfm:1437 +msgid "Options" +msgstr "Optionen" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:76 +#: main.dfm:259 +msgid "Format" +msgstr "Format" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#. frmMain..ActionList1..acFileExit..Category +#. frmMain..ActionList1..acFileClearMemo..Category +#. frmMain..ActionList1..acFileOutputToScreen..Category +#. frmMain..ActionList1..acFileChangeLanguage..Category +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:83 +#: main.dfm:266 +#: main.dfm:1399 +#: main.dfm:1428 +#: main.dfm:1443 +#: main.dfm:1455 +#: main.dfm:1460 +#: main.pas:869 +#: main.pas:923 +msgid "File" +msgstr "Datei" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "Dateneingabe von \"Gerät\"" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:115 +#: main.dfm:299 +msgid "Device" +msgstr "Gerät" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "Optionen für das gewählte Eingabe-Format" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "Lese Daten von Datei ..." + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "Zeichensatz für Eingangsdaten (nicht jedes Format unterstützt dies!)" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:152 +#: main.dfm:363 +msgid "- default -" +msgstr "- Standard -" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "lese von Interface/Anschluß..." + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "Eingabeformat des angeschlossenen Gerätes" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "zu benutzendes Eingabeformat" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:480 +#: main.pas:926 +msgid "Output" +msgstr "Ausgabe" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "Die zu schreibende Datei auswählen" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "Datenausgabe auf \"Gerät\"" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "Ausgabeformat für angeschlossenes Gerät" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "Optionen für das gewählte Ausgabeformat" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "zu benutzendes Ausgabeformat" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "Dateiname für Datenausgabe" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "Zeichensatz für Ausgangsdaten (nicht jedes Format unterstützt dies!)" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "schreibe nach Interface/Anschluß" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "Was?" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "Wegpunkte in Konvertierung einschließen" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "Routen in Konvertierung einschließen" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "&Routen" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "Tracks in Konvertierung einschließen" + +#. frmMain..pnBottom..btnFilter..Caption +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:594 +#: main.dfm:1393 +msgid "&Filter" +msgstr "&Filter" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "Konvertierung starten" + +#. frmMain..pnBottom..btnProcess..Caption +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:641 +#: main.dfm:1386 +msgid "let's go" +msgstr "und los" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "Garmin Mapsource mps|*.mps|Alle Dateien|*.*" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "Alle Dateien|*.*|Garmin MapSource mps|*.mps" + +#. frmMain..ActionList1..acConvert..Category +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1385 +#: main.dfm:1392 +msgid "Babel" +msgstr "Babel" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or device" +msgstr "gelesene Daten filtern" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "Beenden" + +#. frmMain..ActionList1..acHelpAbout..Category +#. frmMain..ActionList1..acHelpIntro..Category +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1404 +#: main.dfm:1409 +#: main.dfm:1413 +msgid "Help" +msgstr "Hilfe" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "Über" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "Einführung" + +#. frmMain..ActionList1..acHelpReadme..Caption +#. frmReadme..Caption +#: main.dfm:1414 +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "GPSBabel README" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "... für Quellformat" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "... für Zielformat" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "Meldungen löschen" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "Meldungen löschen" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "Zeichensatz transformieren" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "Ausgabe auf Bildschirm" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "Sprache ändern" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "&Datei" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "Export" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "&Optionen" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "Synthetisiere Kurznamen" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from description or notes" +msgstr "Ignoriere alle \"Kurznamen\" und generiere diese neu aus Bechreibung oder Bemerkung" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes filter)" +msgstr "Erzwinge Selektion(en)" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "&Hilfe" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "Optionen für ..." + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "Abbrechen" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "Deutsch" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "Französisch" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "Spanisch" + +#: about.pas:131 +msgid "" +"Please have a look at the file README.GUI.\n" +"\n" +"There you will find all information you need to\n" +"get GPSBabelGUI working in your own language." +msgstr "" +"Werfen Sie einen kurzen Blick in die Datei \"README.GUI\"\n" +"\n" +"Dort finden Sie alle nötigen Informationen, um\n" +"GPSBabelGUI eine neue Sprache beizubringen." + +#: filter.pas:178 +#: filter.pas:179 +#: filter.pas:182 +#: filter.pas:183 +msgid "Waypoints" +msgstr "Wegpunkte" + +#: filter.pas:178 +#: filter.pas:179 +#: filter.pas:180 +#: filter.pas:181 +msgid "Routes" +msgstr "Routen" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Tracks" +msgstr "Tracks" + +#: filter.pas:222 +msgid "Feet" +msgstr "\"Feet\" (engl.)" + +#: filter.pas:223 +msgid "Meter" +msgstr "Meter" + +#: filter.pas:226 +msgid "Miles" +msgstr "Meilen" + +#: filter.pas:227 +msgid "Kilometer" +msgstr "Kilometer" + +#: filter.pas:237 +msgid "Not supported by gpsbabel.exe, release %s!" +msgstr "Wird von gpsbabel.exe, Version %s, nicht unterstützt!" + +#: filter.pas:285 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "Wert (%s) liegt außerhalb des zulässigen Bereiches (%g to %g)!" + +#: filter.pas:590 +#: options.pas:661 +msgid "Discard changes?" +msgstr "Änderungen verwerfen?" + +#: main.pas:244 +msgid "Internal development release" +msgstr "Interne Entwicklungsausgabe" + +#: main.pas:246 +msgid "BETA" +msgstr "BETA" + +#: main.pas:248 +msgid "Private release" +msgstr "Private Version" + +#: main.pas:250 +msgid "Special release" +msgstr "Spezial-Version" + +#: main.pas:346 +msgid "The file \"gpsbabel.exe\" found in current directory is too old!" +msgstr "Die Datei \"gpsbabel.exe\" ist zu alt für diese GUI!" + +#: main.pas:420 +#: main.pas:554 +msgid "All files|*.*" +msgstr "Alle Dateien|*.*" + +#: main.pas:488 +msgid "Select and edit options for \"%s\"" +msgstr "Optionen von \"%s\" bearbeiten" + +#: main.pas:492 +msgid "No options available for \"%s\"" +msgstr " \"%s\" hat keine Optionen!" + +#. s := s + '-1'; +#: main.pas:607 +msgid "File %s not found." +msgstr "Datei \"%s\" nicht gefunden." + +#: main.pas:668 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "Datei \"%s\" existiert bereits! Überschreiben?" + +#: main.pas:669 +msgid "Warning" +msgstr "Warnung" + +#: main.pas:702 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "Konnte \"gpsbabel.exe\" nicht ausführen!" + +#: main.pas:711 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "Uhps, da ging etwas schief!" + +#: main.pas:713 +msgid "Converted successfully from \"%s\" to \"%s\"." +msgstr "Erfolgreich konvertiert von \"%s\" zu \"%s\"." + +#: main.pas:824 +msgid "GPSBabel, version %s" +msgstr "GPSBabel, Version %s" + +#: main.pas:858 +#: main.pas:913 +msgid "Port" +msgstr "Schnittstelle" + +#: main.pas:1017 +msgid "Options for \"%s\"" +msgstr "Optionen für \"%s\"" + +#: main.pas:1207 +#: main.pas:1277 +msgid "Choose language" +msgstr "Wähle Sprache" + +#: main.pas:1207 +msgid "for GUIBabelGUI" +msgstr "für GPSBabelGUI" + +#: main.pas:1277 +msgid "for export" +msgstr "für Export" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "Achtung: die meisten Optionen sind vermutlich für die Datenausgabe gedacht." + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used by the options." +msgstr "Wir verfügen z.Z. über kein Merkmal über die Arbeitsweise der Optionen." + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "Abkürzung \"%s\"" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "Ungültiger Zeilenaufbau!" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "Unbekannte Option \"%s\"!" + +#: select.pas:84 +msgid "English" +msgstr "Englisch" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "Fehler WINAPI: \"NamedPipe\" konnte nicht erstellt werden!" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "\"gpsbabel.exe\" wurde nicht gefunden!!!" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error %d)!" +msgstr "Konnte \"gpsbabel.exe\" nicht ausführen (Fehler %d)!" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "\"gpsbabel.exe\" verließ uns mit Fehler 0x%x (%d)!" + diff --git a/win32/gui-2/locale/de/LC_MESSAGES/delphi.po b/win32/gui-2/locale/de/LC_MESSAGES/delphi.po new file mode 100644 index 000000000..6dbc9851a --- /dev/null +++ b/win32/gui-2/locale/de/LC_MESSAGES/delphi.po @@ -0,0 +1,10164 @@ +msgid "" +msgstr "" +"Project-Id-Version: Delphi 5 german\n" +"POT-Creation-Date: 2003-03-04 15:18\n" +"PO-Revision-Date: 2006-04-14 14:12+0100\n" +"Last-Translator: Olaf Klein \n" +"Language-Team: XAN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" + +#. Programmer's name for it: sRowError +#: Decision Cube/mxconsts.pas:27 +msgid "row error" +msgstr "Zeilenfehler" + +#. Programmer's name for it: sAllValues +#: Decision Cube/mxconsts.pas:29 +msgid "All Values" +msgstr "Alle Werte" + +#. Programmer's name for it: sMovetoRow +#: Decision Cube/mxconsts.pas:30 +msgid "Move to Row Area" +msgstr "Zum Zeilenbereich" + +#. Programmer's name for it: sMovetoCol +#: Decision Cube/mxconsts.pas:31 +msgid "Move to Column Area" +msgstr "Zum Spaltenbereich" + +#. Programmer's name for it: sMakeDimOpen +#: Decision Cube/mxconsts.pas:32 +msgid "Open Dimension" +msgstr "Dimension öffnen" + +#. Programmer's name for it: sDrilled +#: Decision Cube/mxconsts.pas:33 +msgid "Drilled In" +msgstr "Untersucht" + +#. Programmer's name for it: sCouldNotOpen +#: Decision Cube/mxconsts.pas:34 +msgid "The information requested could not be loaded. " +msgstr "Die angeforderte Information konnte nicht geladen werden." + +#. Programmer's name for it: sNoSumsAvailable +#: Decision Cube/mxconsts.pas:35 +msgid "No active summaries have been defined. " +msgstr "Es wurden keine aktiven Zusammenfassungen definiert." + +#. Programmer's name for it: sNoSumsCouldBeLoaded +#: Decision Cube/mxconsts.pas:36 +msgid "Not enough room available to load a summary. " +msgstr "Es steht nicht genügend Speicher zur Verfügung, um eine Zusammenfassung zu laden." + +#. Programmer's name for it: sNoDimsAvailable +#: Decision Cube/mxconsts.pas:37 +msgid "No available dimensions have been defined. " +msgstr "Es wurden keine verfügbaren Dimensionen definiert." + +#. Programmer's name for it: sNoDimsCouldBeLoaded +#: Decision Cube/mxconsts.pas:38 +msgid "Not enough space available to load a dimension. " +msgstr "Es steht nicht genügend Speicher zur Verfügung, um eine Dimension zu laden." + +#. Programmer's name for it: sTemplatePrefix +#: Decision Cube/mxconsts.pas:40 +msgid "Template: " +msgstr "Vorlage: " + +#. Programmer's name for it: sGridCellError +#: Decision Cube/mxconsts.pas:42 +msgid "[Error]" +msgstr "[Fehler]" + +#. Programmer's name for it: sTotalCaption +#: Decision Cube/mxconsts.pas:43 +msgid "Sum" +msgstr "Summe" + +#. Programmer's name for it: sActivateLabel +#: Decision Cube/mxconsts.pas:44 +msgid "Inactive Dimensions" +msgstr "Nicht aktive Dimensionen" + +#. Programmer's name for it: sRowCaption +#: Decision Cube/mxconsts.pas:45 +msgid "R" +msgstr "R" + +#. Programmer's name for it: sColCaption +#: Decision Cube/mxconsts.pas:46 +msgid "C" +msgstr "K" + +#. Programmer's name for it: sCaptionMenu1 +#: Decision Cube/mxconsts.pas:47 +msgid "Display Data and Subtotals" +msgstr "Daten und Zwischensummen anzeigen" + +#. Programmer's name for it: sCaptionMenu2 +#: Decision Cube/mxconsts.pas:48 +msgid "Display Data Only" +msgstr "Nur Daten anzeigen" + +#. Programmer's name for it: sCaptionMenu3 +#: Decision Cube/mxconsts.pas:49 +msgid "Display Subtotals Only" +msgstr "Nur Zwischensummen anzeigen" + +#. Programmer's name for it: sDrillIn +#: Decision Cube/mxconsts.pas:50 +msgid "Drill in to this value" +msgstr "Diesen Wert untersuchen" + +#. Programmer's name for it: sGridMenu1 +#: Decision Cube/mxconsts.pas:51 +msgid "Subtotals on/off" +msgstr "Zwischensummen an/aus" + +#. Programmer's name for it: sGridMenu2 +#: Decision Cube/mxconsts.pas:52 +msgid "Decision Cube Editor.." +msgstr "Editor für Entscheidungswürfel..." + +#. Programmer's name for it: sGridMenu3 +#: Decision Cube/mxconsts.pas:53 +msgid "Decision Query Editor.." +msgstr "Editor für Entscheidungsabfrage..." + +#. Programmer's name for it: sGridMenu4 +#: Decision Cube/mxconsts.pas:54 +msgid "Show Detail Records.." +msgstr "Detaildatensätze anzeigen..." + +#. Programmer's name for it: sUnsupportedDataType +#: Decision Cube/mxconsts.pas:57 +msgid "Unsupported data type : %s" +msgstr "Nicht unterstützter Datentyp: %s" + +#. Programmer's name for it: sRowOutOfRange +#: Decision Cube/mxconsts.pas:58 +msgid "Row index out of range : %d" +msgstr "Zeilenindex außerhalb des gültigen Bereichs: %d" + +#. Programmer's name for it: sColOutOfRange +#: Decision Cube/mxconsts.pas:59 +msgid "Column index out of range : %d" +msgstr "Spaltenindex außerhalb des gültigen Bereichs: %d" + +#. Programmer's name for it: sDupeItem +#: Decision Cube/mxconsts.pas:60 +msgid "Duplicate item in array" +msgstr "Im Array befinden sich Doppeleinträge" + +#. Programmer's name for it: sArrayIndexOutOfRange +#: Decision Cube/mxconsts.pas:61 +msgid "Array index out of range : %d" +msgstr "Array-Index außerhalb des gültigen Bereichs: %d" + +#. Programmer's name for it: sLowCapacityError +#: Decision Cube/mxconsts.pas:62 +msgid "The DecisionCube Capacity is low. Please deactivate dimensions or change the data set." +msgstr "Die Kapazität des Entscheidungswürfels ist erschöpft. Deaktivieren Sie einige Dimensionen oder ändern Sie die Datenmenge." + +#. Programmer's name for it: sQryNotInitialized +#: Decision Cube/mxconsts.pas:63 +msgid "Query could not be run. Check that the query, SQL text, and Database are correct." +msgstr "Die Abfrage konnte nicht gestartet werden. Überprüfen Sie, ob Abfrage, SQL-Text und Datenbank korrekt sind." + +#. Programmer's name for it: sSortedListError +#: Decision Cube/mxconsts.pas:64 +msgid "Operation not allowed on sorted string list." +msgstr "Diese Operation ist bei einer sortierten String-Liste nicht erlaubt." + +#. Programmer's name for it: sDuplicateString +#: Decision Cube/mxconsts.pas:65 +msgid "String list does not allow duplicates." +msgstr "Die String-Liste lässt keine Doppeleinträge zu." + +#. Programmer's name for it: sMaxAllowedSums +#: Decision Cube/mxconsts.pas:66 +msgid "The maximum allowed summaries of %d has been exceeded." +msgstr "Das erlaubte Maximum an Zusammenfassungen (%d) wurde überschritten." + +#. Programmer's name for it: sGeneralArrayError +#: Decision Cube/mxconsts.pas:67 +msgid "General array error." +msgstr "Allgemeiner Fehler im Array." + +#. Programmer's name for it: sDimIndexError +#: Decision Cube/mxconsts.pas:70 +msgid "Illegal Dimension Index" +msgstr "Ungültiger Dimensionsindex" + +#. Programmer's name for it: sIllegalValueForBin +#: Decision Cube/mxconsts.pas:73 +msgid "Initial Value is not legal for this type of Grouping" +msgstr "Der Anfangswert ist für diesen Gruppierungstyp nicht erlaubt" + +#. Programmer's name for it: sIllegalDimMap +#: Decision Cube/mxconsts.pas:74 +msgid "Dimension Map is not the correct size" +msgstr "Die Größe der Dimensionszuweisung ist nicht korrekt" + +#. Programmer's name for it: sDimMapActiveError +#: Decision Cube/mxconsts.pas:75 +msgid "Cannot perform this action on an active Dimension Map" +msgstr "Diese Aktion kann nicht auf eine aktive Dimensionszuweisung angewendet werden" + +#. Programmer's name for it: sNotAvailable +#: Decision Cube/mxconsts.pas:76 +msgid "Not Available" +msgstr "Nicht verfügbar" + +#. Programmer's name for it: sGetValueCounts +#: Decision Cube/mxconsts.pas:77 +msgid "Information required to do Maximum Cell limit is not current. Do you want to fetch it now?" +msgstr "Die Information für das Berechnen des Zellmaximums ist nicht mehr aktuell. Soll diese Information aktualisiert werden?" + +#. Programmer's name for it: sDateBinningNotAllowed +#: Decision Cube/mxconsts.pas:78 +msgid "Date grouping is not allowed for fields of this type" +msgstr "Die Gruppierung nach Datum ist für diesen Feldtyp nicht erlaubt" + +#. Programmer's name for it: sEmptyDataSet +#: Decision Cube/mxconsts.pas:79 +msgid "Cannot build the Decision Cube with an empty data set" +msgstr "Der Entscheidungswürfel kann nicht mit einer leeren Datenmenge erstellt werden" + +#. Programmer's name for it: sNoDataSet +#: Decision Cube/mxconsts.pas:82 +msgid "Data set property is not assigned" +msgstr "Der Eigenschaft Data Set wurde kein Wert zugewiesen" + +#. Programmer's name for it: sNoAggs +#: Decision Cube/mxconsts.pas:83 +msgid "No summaries are defined. " +msgstr "Es sind keine Zusammenfassungen definiert." + +#. Programmer's name for it: sNoDims +#: Decision Cube/mxconsts.pas:84 +msgid "No dimension fields are defined. " +msgstr "Es sind keine Dimensionsfelder definiert." + +#. Programmer's name for it: sUnknownDims +#: Decision Cube/mxconsts.pas:85 +msgid "The dimension types for this dataset cannot be determined automatically. You must map the fields to dimensions or summaries with the Decision Cube Editor" +msgstr "Die Dimensionstypen für diese Datenmenge können nicht automatisch festgelegt werden. Sie müssen diese Felder mit dem Editor für Entscheidungswürfel einer Dimension oder Zusammenfassung zuweisen." + +#. Programmer's name for it: sGroupsMissing +#: Decision Cube/mxconsts.pas:86 +msgid "All dimension fields must be grouped. " +msgstr "Alle Dimensionsfelder müssen gruppiert werden." + +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#: Decision Cube/mxconsts.pas:87 +#: Vcl/mxconsts.pas:89 +msgid "The query may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "Die Abfrage wurde inkorrekt definiert oder die Felder der Abfrage müssen mit dem Editor für Entscheidungswürfel aktiven Dimensionen oder Zusammenfassungen zugewiesen werden" + +#. Programmer's name for it: sDataSetError +#: Decision Cube/mxconsts.pas:88 +msgid "The dataset may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "Die Datenmenge wurde inkorrekt definiert oder die Felder müssen mit dem Editor für Entscheidungswürfel aktiven Dimensionen oder Zusammenfassungen zugewiesen werden" + +#. Programmer's name for it: sCountStar +#: Decision Cube/mxconsts.pas:90 +msgid "COUNTALL" +msgstr "COUNTALL" + +#. Programmer's name for it: sAddAvgWarning +#: Decision Cube/mxconsts.pas:91 +msgid "Average is calculated using sum and count summaries for each field. The necessary summaries have been added." +msgstr "Der Mittelwert wird durch Ermittlung der Summe und der Anzahl für jedes Feld ermittelt. Die dazu notwendigen Zusammenfassungen wurden hinzugefügt." + +#. Programmer's name for it: sAddAvgStarWarning +#: Decision Cube/mxconsts.pas:92 +msgid "Average is calculated using a field sum and count(*). The necessary summaries have been added." +msgstr "Der Mittelwert wird durch Ermittlung der Feldsumme und count(*) ermittelt. Die dazu notwendigen Zusammenfassungen wurden hinzugefügt." + +#. Programmer's name for it: sQueryLegal +#: Decision Cube/mxconsts.pas:95 +msgid "Query is legal." +msgstr "Die Abfrage ist gültig." + +#. Programmer's name for it: sAddFieldExists +#: Decision Cube/mxconsts.pas:96 +msgid " is already in the query" +msgstr " ist bereits in der Abfrage" + +#. Programmer's name for it: sAggTypeNotAllowed +#: Decision Cube/mxconsts.pas:97 +msgid " is not an allowed summary type" +msgstr " ist kein erlaubter Zusammenfassungstyp" + +#. Programmer's name for it: sDimTypeNotAllowed +#: Decision Cube/mxconsts.pas:98 +msgid " is not an allowed dimension type" +msgstr " ist kein erlaubter Dimensionstyp" + +#. Programmer's name for it: sAverageRequires +#: Decision Cube/mxconsts.pas:99 +msgid "Average summaries use Sum and Count" +msgstr "Mittelwert verwendet Summe und Anzahl" + +#. Programmer's name for it: sWantToExit +#: Decision Cube/mxconsts.pas:100 +msgid "Do you still want to Exit?" +msgstr "Wollen Sie wirklich beenden?" + +#. Programmer's name for it: sQueryIllegal +#: Decision Cube/mxconsts.pas:101 +msgid "The query you have created is not legal." +msgstr "Die von Ihnen erstellte Abfrage ist ungültig." + +#. Programmer's name for it: sQueryEditIllegal +#: Decision Cube/mxconsts.pas:102 +msgid "The query you have entered is not legal. Please correct it before continuing." +msgstr "Die eingegebene Abfrage ist ungültig. Sie muß geändert werden, bevor Sie weitermachen." + +#. Programmer's name for it: sRemoveFieldError +#: Decision Cube/mxconsts.pas:103 +msgid "Could not remove the field" +msgstr "Das Feld konnte nicht entfernt werden" + +#. Programmer's name for it: sAllFields +#: Decision Cube/mxconsts.pas:104 +msgid "All Fields" +msgstr "&Alle Felder" + +#. Programmer's name for it: sQueryFields +#: Decision Cube/mxconsts.pas:105 +msgid "Query Fields" +msgstr "Felder abfragen" + +#. Programmer's name for it: sEditDone +#: Decision Cube/mxconsts.pas:106 +msgid "&Edit Done" +msgstr "Bearbeitung &abschließen" + +#. Programmer's name for it: sEditQuery +#. DSSQueryEditor..Pager..Query..EditQry..Caption +#: Decision Cube/mxconsts.pas:107 +msgid "&Edit Query" +msgstr "Ab&frage bearbeiten" + +#. Programmer's name for it: sQParseRemovedField +#: Decision Cube/mxconsts.pas:110 +msgid "One or more fields of a type which cannot be tabulated were removed from the query." +msgstr "Ein oder mehrere Felder wurden aus der Abfrage entfernt, da sie nicht tabularisiert werden konnten." + +#. Programmer's name for it: sCubeLimitsExceeded +#: Decision Cube/mxconsts.pas:113 +msgid "Decision Cube size excedes limits" +msgstr "Der Entscheidungswürfel überschreitet seine Kapazität" + +#. Programmer's name for it: sMaxAllowedDims +#: Decision Cube/mxconsts.pas:114 +msgid "The maximum allowed dimensions of %d has been exceeded." +msgstr "Das erlaubte Maximum an Dimensionen (%d) wurde überschritten." + +#. Programmer's name for it: sMaxAllowedCells +#: Decision Cube/mxconsts.pas:115 +msgid "Total cell count of %d exceeds the maximum of %d." +msgstr "Die Gesamtanzahl an Zellen von %d überschreitet das Maximum von %d." + +#. Programmer's name for it: sUnsupportedFieldType +#: Decision Cube/mxconsts.pas:116 +msgid "Field %s has an unsupported data type: %s" +msgstr "Feld %s ist vom nicht unterstützten Datentyp %s" + +#. Programmer's name for it: sFetchValues +#: Decision Cube/mxconsts.pas:117 +msgid "Scanning data set values..." +msgstr "Datenwerte analysieren..." + +#. Programmer's name for it: sUserCanceled +#: Decision Cube/mxconsts.pas:118 +msgid "User canceled DecisionCube population." +msgstr "Das Füllen des Entscheidungswürfels wurde durch den Anwender unterbrochen." + +#. Programmer's name for it: sBinningValues +#: Decision Cube/mxconsts.pas:119 +msgid "Grouping values ..." +msgstr "Werte gruppieren..." + +#. Programmer's name for it: sCreatingIndexes +#: Decision Cube/mxconsts.pas:120 +msgid "Creating Cube index for %s ..." +msgstr "Erstellen des Würfelindex für %s..." + +#. Programmer's name for it: sCreateDerivedSummaryError +#: Decision Cube/mxconsts.pas:121 +msgid "Unable to create derived summary." +msgstr "Abgeleitete Zusammenfassung konnte nicht erzeugt werden." + +#. Programmer's name for it: sTrue +#. Programmer's name for it: STextTrue +#. Programmer's name for it: sTrue +#: Decision Cube/mxconsts.pas:122 +msgid "True" +msgstr "Wahr" + +#. Programmer's name for it: sFalse +#. Programmer's name for it: STextFalse +#. Programmer's name for it: sFalse +#: Decision Cube/mxconsts.pas:123 +msgid "False" +msgstr "Falsch" + +#. Programmer's name for it: sBinTypeMismatch +#: Decision Cube/mxconsts.pas:124 +msgid "The bin type does not match the fieldtype." +msgstr "Der Gruppierungstyp entspricht nicht dem Feldtyp." + +#. Programmer's name for it: sFatalCacheError +#: Decision Cube/mxconsts.pas:125 +msgid "Fatal error in cache: code: %d" +msgstr "Schwerer Fehler im Cache: Code: %d" + +#. Programmer's name for it: sStringTypeNoSupported +#: Decision Cube/mxconsts.pas:126 +msgid "String Data type not supported for summaries" +msgstr "Datentyp String wird von Zusammenfassungen nicht unterstützt" + +#. Programmer's name for it: sDataSetTooLarge +#: Decision Cube/mxconsts.pas:127 +msgid "Dataset is too large" +msgstr "Datenmenge ist zu groß" + +#. Programmer's name for it: sBuildingDataStore +#: Decision Cube/mxconsts.pas:128 +msgid "Building data store..." +msgstr "Datenspeicher aufbauen..." + +#. Programmer's name for it: sSumLabel +#: Decision Cube/mxconsts.pas:131 +msgid "Sum of %s" +msgstr "Summe von %s" + +#. Programmer's name for it: sCountLabel +#: Decision Cube/mxconsts.pas:132 +msgid "Count of %s" +msgstr "Anzahl von %s" + +#. Programmer's name for it: sMaxLabel +#: Decision Cube/mxconsts.pas:133 +msgid "Maximum of %s" +msgstr "Maximum von %s" + +#. Programmer's name for it: sMinLabel +#: Decision Cube/mxconsts.pas:134 +msgid "Minimum of %s" +msgstr "Minimum von %s" + +#. Programmer's name for it: sAverageLabel +#: Decision Cube/mxconsts.pas:135 +msgid "Average of %s" +msgstr "Mittelwert von %s" + +#. Programmer's name for it: sVarLabel +#: Decision Cube/mxconsts.pas:136 +msgid "Variance of %s" +msgstr "Varianz von %s" + +#. Programmer's name for it: sSDLabel +#: Decision Cube/mxconsts.pas:137 +msgid "Standard Deviation of %s" +msgstr "Standardabweichung von %s" + +#. Programmer's name for it: sAggLabel +#: Decision Cube/mxconsts.pas:138 +msgid "Summary of %s" +msgstr "Zusammenfassung von: %s" + +#. Programmer's name for it: sUnsupportedVarType +#: Decision Cube/mxconsts.pas:139 +msgid "Unsupported Data Type %d" +msgstr "Nicht unterstützter Datentyp: %d" + +#. Programmer's name for it: sOtherValues +#: Decision Cube/mxconsts.pas:140 +msgid "Other Values" +msgstr "Andere Werte" + +#. Programmer's name for it: sSelectFromError +#: Decision Cube/mxconsts.pas:142 +msgid "Query lacks a Select/From clause." +msgstr "Der Abfrage fehlt eine Select/From-Klausel." + +#. Programmer's name for it: sArgumentExpected +#: Decision Cube/mxconsts.pas:143 +msgid "No argument provided for an operator or summary" +msgstr "Für einen Operator oder eine Zusammenfassung fehlt ein Argument" + +#. Programmer's name for it: sGroupOnExpressionError +#: Decision Cube/mxconsts.pas:144 +msgid "An expression cannot be used for a grouping field" +msgstr "Ein Ausdruck kann nicht zum Gruppieren eines Feldes verwendet werden" + +#. Programmer's name for it: SOutofBounds +#: Decision Cube/mxconsts.pas:146 +msgid "Out of Bounds" +msgstr "Außerhalb des Bereichs" + +#. Programmer's name for it: sIDAPILangID +#. Programmer's name for it: SIDAPILangID +#. Programmer's name for it: sIDAPILangID +#: Decision Cube/mxconsts.pas:147 +msgid "0009" +msgstr "0007" + +#. Programmer's name for it: sComponentTabName +#: Decision Cube/mxdconst.pas:14 +msgid "Decision Cube" +msgstr "Datenanalyse" + +#. Programmer's name for it: sQueryVerb0 +#: Decision Cube/mxdconst.pas:15 +msgid "&Graphical Query Builder..." +msgstr "&Grafischer Abfragegenerator..." + +#. Programmer's name for it: sQueryVerb1 +#: Decision Cube/mxdconst.pas:16 +msgid "&Decision Query Editor..." +msgstr "&Editor für Entscheidungsabfrage..." + +#. Programmer's name for it: sCubeVerb0 +#: Decision Cube/mxdconst.pas:17 +msgid "&Decision Cube Editor..." +msgstr "&Editor für Entscheidungsanalyse..." + +#. Programmer's name for it: sCubeVerb1 +#: Decision Cube/mxdconst.pas:18 +msgid "&Query Editor..." +msgstr "Abfragee&ditor..." + +#. Programmer's name for it: sGridVerb0 +#: Decision Cube/mxdconst.pas:19 +msgid "Sub&totals on/off" +msgstr "&Zwischensummen an/aus" + +#. Programmer's name for it: sSourceVerb0 +#: Decision Cube/mxdconst.pas:20 +msgid "&Do not display Sparse Rows/Columns" +msgstr "S&palten/Zeilen mit wenig Werten nicht anzeigen" + +#. Programmer's name for it: sSourceVerb1 +#: Decision Cube/mxdconst.pas:21 +msgid "&Display Sparse Rows/Columns" +msgstr "S&palten/Zeilen mit wenig Werten anzeigen" + +#. Programmer's name for it: sGridDimOptions +#: Decision Cube/mxdconst.pas:22 +msgid "Grid Dimension Options" +msgstr "Optionen für Rasterdimension" + +#. Programmer's name for it: sGridDimSettings +#: Decision Cube/mxdconst.pas:23 +msgid "Grid Dimension Settings" +msgstr "Einstellung für Rasterdimension" + +#. Programmer's name for it: sCubeProperties +#: Decision Cube/mxdconst.pas:24 +msgid "Cube Properties" +msgstr "Würfeleigenschaften" + +#. Programmer's name for it: sOnlyOneDataModuleAllowed +#: Internet/brkrconst.pas:14 +msgid "Only one data module per application" +msgstr "Nur ein Datenmodul pro Anwendung" + +#. Programmer's name for it: sNoDataModulesRegistered +#: Internet/brkrconst.pas:15 +msgid "No data modules registered" +msgstr "Es wurden keine Datenmodule registriert" + +#. Programmer's name for it: sNoDispatcherComponent +#: Internet/brkrconst.pas:16 +msgid "No dispatcher component found on data module" +msgstr "Im Datenmodul wurde keine Dispatcher-Komponente gefunden" + +#. Programmer's name for it: sTooManyActiveConnections +#: Internet/brkrconst.pas:18 +msgid "Maximum number of concurrent connections exceeded. Please try again later" +msgstr "Die maximale Anzahl gleichzeitiger Verbindungen wurde überschritten. Versuchen Sie später noch erneut" + +#. Programmer's name for it: sInternalServerError +#: Internet/brkrconst.pas:22 +msgid "" +"Internal Server Error 500\n" +"

Internal Server Error 500


\n" +"Exception: %s
\n" +"Message: %s
\n" +msgstr "" +"Interner Server-Fehler 500\n" +"

Interner Server-Fehlerr 500


\n" +"Exception: %s
\n" +"Meldung: %s
\n" + +#. Programmer's name for it: sDocumentMoved +#: Internet/brkrconst.pas:26 +msgid "" +"Document Moved 302\n" +"

Object Moved


\n" +"This Object may be found
here.
\n" +"
\n" +msgstr "" +"Dokument wurde verschoben 302\n" +"

Objekt wurde verschoben


\n" +"Das Objekt könnte hier gefunden werden.
\n" +"
\n" + +#. Programmer's name for it: sInvalidISAPIApp +#: Internet/nstois.pas:109 +msgid "Invalid ISAPI application: %s" +msgstr "Ungültige ISAPI-Anwendung: %s" + +#. Programmer's name for it: sUnSupportedISAPIApp +#: Internet/nstois.pas:110 +msgid "Unsupported ISAPI Application version: %.8x" +msgstr "Nicht unterstützte ISAPI-Anwendungsversion: %.8x" + +#. Programmer's name for it: sGEVFailed +#: Internet/nstois.pas:111 +msgid "Call to GetExtensionVersion FAILED. Error Code: %d" +msgstr "Aufruf von GetExtensionVersion FEHLGESCHLAGEN. Fehler-Code: %d" + +#. Programmer's name for it: sErrorLoadingISAPIApp +#: Internet/nstois.pas:112 +msgid "Error loading ISAPI Application: %s" +msgstr "Fehler beim Laden von ISAPI-Anwendung %s" + +#. Programmer's name for it: sInvalidRedirectParam +#: Internet/nstois.pas:113 +msgid "Invalid Redirect parameter" +msgstr "Ungültiger Redirect-Parameter" + +#. Programmer's name for it: sISAPIAppError +#: Internet/nstois.pas:114 +msgid "ISAPI Application Error" +msgstr "Fehler in ISAPI-Anwendung" + +#. Programmer's name for it: sDataSetFieldBlank +#: Internet/wbmconst.pas:15 +msgid "Data set field is blank" +msgstr "Datenmengenfeld ist leer" + +#. Programmer's name for it: sDataSetFieldNotFound +#: Internet/wbmconst.pas:16 +msgid "Data set field not found: %s" +msgstr "Feld der Datenmenge nicht gefunden %s" + +#. Programmer's name for it: sNotDataSetField +#: Internet/wbmconst.pas:17 +msgid "Field is not a dataset field: %s" +msgstr "Feld ist kein Feld aus der Datenmenge: %s" + +#. Programmer's name for it: ScriptTableName +#: Internet/wbmconst.pas:18 +msgid "%s_Table" +msgstr "%s_Table" + +#. Programmer's name for it: sNoXMLBroker +#: Internet/wbmconst.pas:19 +msgid "%s: missing XMLBroker" +msgstr "%s: XMLBroker fehlt" + +#. Programmer's name for it: sFieldNotFound +#: Internet/wbmconst.pas:20 +msgid "%0:s: Field \"%1:s\" not found" +msgstr "%0:s: Feld \"%1:s\" nicht gefunden" + +#. Programmer's name for it: sXMLBrokerNotDefined +#: Internet/wbmconst.pas:21 +msgid "%s.XMLBroker = nil" +msgstr "%s.XMLBroker = nil" + +#. Programmer's name for it: sSubmitQuery +#: Internet/wbmconst.pas:22 +msgid "Submit" +msgstr "Absenden" + +#. Programmer's name for it: sResetQuery +#: Internet/wbmconst.pas:23 +msgid "Reset" +msgstr "Zurücksetzen" + +#. Programmer's name for it: sApplyUpdates +#: Internet/wbmconst.pas:24 +msgid "Apply Updates" +msgstr "Aktualisierung durchführen" + +#. Programmer's name for it: sFieldNameBlank +#: Internet/wbmconst.pas:25 +msgid "%s.FieldName = ''" +msgstr "%s.FieldName = ''" + +#. Programmer's name for it: sXMLComponentNotDefined +#: Internet/wbmconst.pas:26 +msgid "%s.XMLComponent = nil" +msgstr "%s.XMLComponent = nil" + +#. Programmer's name for it: ScriptNamesVar +#: Internet/wbmconst.pas:27 +msgid "%s_Names" +msgstr "%s_Names" + +#. Programmer's name for it: ScriptIDsVar +#: Internet/wbmconst.pas:28 +msgid "%s_IDs" +msgstr "%s_IDs" + +#. Programmer's name for it: ScriptXMLDisplayName +#: Internet/wbmconst.pas:29 +msgid "%s_Disp" +msgstr "%s_Disp" + +#. Programmer's name for it: sInvalidParent +#: Internet/wbmconst.pas:30 +msgid "Invalid parent" +msgstr "Ungültiges übergeordnetes Element" + +#. Programmer's name for it: sDuplicateStatusField +#: Internet/wbmconst.pas:31 +msgid "Field %s ignored, only one status field allowed" +msgstr "Feld %s wird ignoriert, es ist nur ein Statusfeld gestattet" + +#. Programmer's name for it: sFirstButton +#: Internet/wbmconst.pas:32 +msgid "|<" +msgstr "|<" + +#. Programmer's name for it: sLastButton +#: Internet/wbmconst.pas:33 +msgid ">|" +msgstr ">|" + +#. Programmer's name for it: sPriorButton +#: Internet/wbmconst.pas:34 +msgid "<" +msgstr "<" + +#. Programmer's name for it: sNextButton +#: Internet/wbmconst.pas:35 +msgid ">" +msgstr ">" + +#. Programmer's name for it: sPriorPageButton +#: Internet/wbmconst.pas:36 +msgid "<<" +msgstr "<<" + +#. Programmer's name for it: sNextPageButton +#: Internet/wbmconst.pas:37 +msgid ">>" +msgstr ">>" + +#. Programmer's name for it: sDeleteButton +#: Internet/wbmconst.pas:38 +msgid " - " +msgstr " - " + +#. Programmer's name for it: sInsertButton +#: Internet/wbmconst.pas:39 +msgid " + " +msgstr " + " + +#. Programmer's name for it: sUndoButton +#: Internet/wbmconst.pas:40 +msgid "Undo" +msgstr "Rückgängig" + +#. Programmer's name for it: sPostButton +#: Internet/wbmconst.pas:41 +msgid "Post" +msgstr "Übernehmen" + +#. Programmer's name for it: sWarningsBody +#: Internet/wbmconst.pas:46 +msgid "" +"\n" +"\n" +"

Design-time Warnings

\n" +"%s\n" +"

\n" +msgstr "" +"\n" +"\n" +"

Warnungen zur Entwurfszeit

\n" +"%s\n" +"

\n" + +#. Programmer's name for it: ScriptDocumentVarName +#: Internet/wbmconst.pas:47 +msgid "%s_Doc" +msgstr "%s_Doc" + +#. Programmer's name for it: ScriptXMLVarName +#: Internet/wbmconst.pas:48 +msgid "%s_XML" +msgstr "%s_XML" + +#. Programmer's name for it: sInvalidWebComponentsRegistration +#: Internet/wbmconst.pas:49 +msgid "Invalid Web component registration" +msgstr "Ungültige Registrierung der Web-Komponente" + +#. Programmer's name for it: sInvalidWebComponentsEnumeration +#: Internet/wbmconst.pas:50 +msgid "Invalid Web component enumeration" +msgstr "Ungültige Enumeration von Web-Komponente" + +#. Programmer's name for it: sInvalidWebComponentsCreation +#: Internet/wbmconst.pas:51 +msgid "Invalid Web component creation" +msgstr "Fehlendes Delta-Paket" + +#. Programmer's name for it: ScriptRowSetVarName +#: Internet/wbmconst.pas:52 +msgid "%s_RS" +msgstr "%s_RS" + +#. Programmer's name for it: sApplyUpdatesError +#: Internet/wbmconst.pas:53 +msgid "ApplyUpdates error. Error count: %d." +msgstr "DataSet: %s ist nicht aktiv" + +#. Programmer's name for it: sDeltaNotFound +#: Internet/wbmconst.pas:54 +msgid "Missing Delta Packet" +msgstr "Fehlendes Delta-Paket" + +#. Programmer's name for it: sXMLBrokerNotConnected +#: Internet/wbmconst.pas:55 +msgid "XMLBroker: %s is not connected" +msgstr "XMLBroker: %s hat keine Verbindung" + +#. Programmer's name for it: sDataSetNotActive +#: Internet/wbmconst.pas:56 +msgid "DataSet: %s is not active" +msgstr "DataSet: %s ist nicht aktiv" + +#. Programmer's name for it: SNewLookupFieldCaption +#: Property Editors/dsdefine.pas:442 +msgid "New Lookup Field" +msgstr "Neues Nachschlagefeld" + +#. Programmer's name for it: srSamples +#: Samples/ibconst.pas:6 +msgid "Samples" +msgstr "Beispiele" + +#. Programmer's name for it: SNoEventsRegistered +#: Samples/ibconst.pas:7 +msgid "You must register events before queueing them" +msgstr "Ereignisse müssen registriert werden, bevor sie in die Warteschlange gestellt werden können" + +#. Programmer's name for it: SInvalidDBConnection +#: Samples/ibconst.pas:8 +msgid "Component is not connected to an open Database" +msgstr "Die Komponente ist nicht mit einer offenen Datenbank verbunden" + +#. Programmer's name for it: SInvalidDatabase +#: Samples/ibconst.pas:9 +msgid "''%s'' is not connected to an InterBase database" +msgstr "''%s'' ist nicht mit einer InterBase-Datenbank verbunden" + +#. Programmer's name for it: SInvalidCancellation +#: Samples/ibconst.pas:10 +msgid "You cannot call CancelEvents from within an OnEventAlert handler" +msgstr "CancelEvents kann nicht aus einer OnEventAlert-Behandlungsroutine heraus aufgerufen werden" + +#. Programmer's name for it: SInvalidEvent +#: Samples/ibconst.pas:11 +msgid "Invalid blank event added to EventAlerter events list" +msgstr "Der Ereignisliste des Event-Alerters wurde ein ungültiges leeres Ereignis hinzugefügt" + +#. Programmer's name for it: SInvalidQueueing +#: Samples/ibconst.pas:12 +msgid "You cannot call QueueEvents from within an OnEventAlert handler" +msgstr "QueueEvents kann nicht aus einem OnEventAlert-Behandlungsroutine heraus aufgerufen werden" + +#. Programmer's name for it: SInvalidRegistration +#: Samples/ibconst.pas:13 +msgid "You cannot Register or Unregister events from within an OnEventAlert handler" +msgstr "Die Registrierung von Ereignissen bzw. deren Aufhebung kann nicht von innerhalb einer OnEventAlert-Behandlung vorgenommen werden" + +#. Programmer's name for it: SMaximumEvents +#: Samples/ibconst.pas:13 +msgid "You can only register 15 events per EventAlerter" +msgstr "Es können nur 15 Ereignisse pro Event-Alerter registriert werden" + +#. Programmer's name for it: SInterbaseNotInstalled +#: Samples/ibctrls.pas:103 +msgid "You must have Interbase installed to use this component" +msgstr "Um diese Komponenten verwenden zu können, muß InterBase installiert sein." + +#. Programmer's name for it: SFailedQueEvents +#: Samples/ibctrls.pas:104 +msgid "Failed to lookup isc_que_events" +msgstr "isc_que_events konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedInterprete +#: Samples/ibctrls.pas:105 +msgid "Failed to lookup isc_interprete" +msgstr "isc_interprete konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedFree +#: Samples/ibctrls.pas:106 +msgid "Failed to lookup isc_free" +msgstr "isc_free konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedEventBlock +#: Samples/ibctrls.pas:107 +msgid "Failed to lookup isc_event_block" +msgstr "isc_event_block konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedEventCounts +#: Samples/ibctrls.pas:108 +msgid "Failed to lookup isc_event_counts" +msgstr "isc_event_counts konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SFailedCancelEvents +#: Samples/ibctrls.pas:109 +msgid "Failed to lookup isc_cancel_events" +msgstr "isc_cancel_events konnte nicht nachgeschlagen werden" + +#. Programmer's name for it: SInvalidEnumValue +#: Vcl/adoconst.pas:15 +msgid "Invalid Enum Value" +msgstr "Ungültiger Enum-Wert" + +#. Programmer's name for it: SMissingConnection +#: Vcl/adoconst.pas:16 +msgid "Missing Connection or ConnectionString" +msgstr "Fehlende Connection oder ConnectionString" + +#. Programmer's name for it: SNoDetailFilter +#: Vcl/adoconst.pas:17 +msgid "Filter property cannot be used for detail tables" +msgstr "Die Filter-Eigenschaft kann nicht bei Detail-Tabellen verwendet werden" + +#. Programmer's name for it: SBookmarksRequired +#: Vcl/adoconst.pas:18 +msgid "Dataset does not support bookmarks, which are required for multi-record data controls" +msgstr "Die Datenmenge unterstützt keine Positionsmarken, die von Multi-Datensatz-Elementen benötigt werden." + +#. Programmer's name for it: SMissingCommandText +#: Vcl/adoconst.pas:19 +msgid "Missing %s property" +msgstr "Eigenschaft %s fehlt" + +#. Programmer's name for it: SNoResultSet +#: Vcl/adoconst.pas:20 +msgid "CommandText does not return a result set" +msgstr "CommandText gibt keine Ergebnismenge zurück" + +#. Programmer's name for it: SADOCreateError +#: Vcl/adoconst.pas:21 +msgid "Error creating object. Please verify that the Microsoft Data Access Components 2.1 (or later) have been properly installed" +msgstr "Fehler bei der Objekterzeugung. Stellen Sie sicher, daß die Microsoft Data Access Components 2.1 (oder höher) richtig installiert sind" + +#. Programmer's name for it: SEventsNotSupported +#: Vcl/adoconst.pas:22 +msgid "Events are not supported with server side TableDirect cursors" +msgstr "Ereignisse werden nicht mit server-seitigen TableDirect-Cursorn unterstützt" + +#. Programmer's name for it: SUsupportedFieldType +#: Vcl/adoconst.pas:23 +msgid "Unsupported field type (%s) in field %s" +msgstr "Nicht unterstützter Feldtyp (%s) in Feld %s" + +#. Programmer's name for it: SNoMatchingADOType +#: Vcl/adoconst.pas:24 +msgid "No matching ADO data type for %s" +msgstr "Kein passender ADO-Datentyp für %s" + +#. Programmer's name for it: SConnectionRequired +#: Vcl/adoconst.pas:25 +msgid "A connection component is required for async ExecuteOptions" +msgstr "Für asynchrone ExecuteOptions wird eine Verbindungskomponente erwartet" + +#. Programmer's name for it: SCantRequery +#: Vcl/adoconst.pas:26 +msgid "Cannot perform a requery after connection has changed" +msgstr "Nach Wechsel der Verbindung kann keine Abfrage durchgeführt werden" + +#. Programmer's name for it: SNoFilterOptions +#: Vcl/adoconst.pas:27 +msgid "FilterOptions are not supported" +msgstr "Filteroptionen werden nicht unterstützt" + +#. Programmer's name for it: SAutoSessionExclusive +#: Vcl/bdeconst.pas:15 +msgid "Cannot enable AutoSessionName property with more than one session on a form or data-module" +msgstr "Die Eigenschaft AutoSessionName kann nicht aktiviert werden, wenn sich mehr als eine Session in einem Formular oder einem Datenmodul befinden" + +#. Programmer's name for it: SAutoSessionExists +#: Vcl/bdeconst.pas:16 +msgid "Cannot add a session to the form or data-module while session '%s' has AutoSessionName enabled" +msgstr "Einem Formular oder Datenmodul kann keine Session hinzugefügt werden, da Session '%s' AutoSessionName aktiviert hat" + +#. Programmer's name for it: SAutoSessionActive +#: Vcl/bdeconst.pas:17 +msgid "Cannot modify SessionName while AutoSessionName is enabled" +msgstr "Während AutoSessionName aktiviert ist, kann SessionName nicht geändert werden." + +#. Programmer's name for it: SDuplicateDatabaseName +#: Vcl/bdeconst.pas:18 +msgid "Duplicate database name '%s'" +msgstr "Doppelter Datenbankname '%s'" + +#. Programmer's name for it: SDuplicateSessionName +#: Vcl/bdeconst.pas:19 +msgid "Duplicate session name '%s'" +msgstr "Doppelter Name für eine Sitzung: '%s'" + +#. Programmer's name for it: SInvalidSessionName +#: Vcl/bdeconst.pas:20 +msgid "Invalid session name %s" +msgstr "Ungültiger Sitzungsname %s" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/bdeconst.pas:21 +msgid "Database name missing" +msgstr "Datenbankname fehlt" + +#. Programmer's name for it: SSessionNameMissing +#: Vcl/bdeconst.pas:22 +msgid "Session name missing" +msgstr "Name der Sitzung fehlt" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/bdeconst.pas:23 +msgid "Cannot perform this operation on an open database" +msgstr "Operation bei geöffneter Datenbank nicht ausführbar" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/bdeconst.pas:24 +msgid "Cannot perform this operation on a closed database" +msgstr "Operation bei geschlossener Datenbank nicht ausführbar" + +#. Programmer's name for it: SDatabaseHandleSet +#: Vcl/bdeconst.pas:25 +msgid "Database handle owned by a different session" +msgstr "Datenbank-Handle gehört zu einer anderen Sitzung" + +#. Programmer's name for it: SSessionActive +#: Vcl/bdeconst.pas:26 +msgid "Cannot perform this operation on an active session" +msgstr "Diese Operation kann auf eine aktive Sitzung nicht angewendet werden" + +#. Programmer's name for it: SHandleError +#: Vcl/bdeconst.pas:27 +msgid "Error creating cursor handle" +msgstr "Fehler beim Erstellen des Cursor-Handle" + +#. Programmer's name for it: SInvalidFloatField +#: Vcl/bdeconst.pas:28 +msgid "Cannot convert field '%s' to a floating point value" +msgstr "Feld '%s' kann nicht in Fließkommawert konvertiert werden" + +#. Programmer's name for it: SInvalidIntegerField +#: Vcl/bdeconst.pas:29 +msgid "Cannot convert field '%s' to an integer value" +msgstr "Feld '%s' kann nicht in Integerwert konvertiert werden" + +#. Programmer's name for it: STableMismatch +#: Vcl/bdeconst.pas:30 +msgid "Source and destination tables are incompatible" +msgstr "Quell- und Zieltabellen sind inkompatibel" + +#. Programmer's name for it: SFieldAssignError +#: Vcl/bdeconst.pas:31 +msgid "Fields '%s' and '%s' are not assignment compatible" +msgstr "Die Felder '%s' und '%s' sind nicht zuweisungskompatibel" + +#. Programmer's name for it: SNoReferenceTableName +#: Vcl/bdeconst.pas:32 +msgid "ReferenceTableName not specified for field '%s'" +msgstr "Für Feld '%s' wurde kein Referenztabellenname angegeben" + +#. Programmer's name for it: SCompositeIndexError +#: Vcl/bdeconst.pas:33 +msgid "Cannot use array of Field values with Expression Indices" +msgstr "Ein Array von Feldwerten kann nicht mit auf Ausdrücken basierenden Indizes verwendet werden" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/bdeconst.pas:34 +msgid "Invalid batch move parameters" +msgstr "Ungültige Batch-Move-Parameter" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/bdeconst.pas:35 +msgid "No SQL statement available" +msgstr "Keine SQL-Anweisung verfügbar" + +#. Programmer's name for it: SNoParameterValue +#: Vcl/bdeconst.pas:36 +msgid "No value for parameter '%s'" +msgstr "Fehlender Wert für Parameter '%s'" + +#. Programmer's name for it: SNoParameterType +#: Vcl/bdeconst.pas:37 +msgid "No parameter type for parameter '%s'" +msgstr "Kein Parametertyp für Parameter '%s'" + +#. Programmer's name for it: SLoginError +#: Vcl/bdeconst.pas:38 +msgid "Cannot connect to database '%s'" +msgstr "Verbindung zu Datenbank '%s' nicht möglich" + +#. Programmer's name for it: SInitError +#: Vcl/bdeconst.pas:39 +msgid "An error occurred while attempting to initialize the Borland Database Engine (error $%.4x)" +msgstr "Bei der Initialisierung der Borland Database Engine ist ein Fehler aufgetreten (Fehler $%.4x)" + +#. Programmer's name for it: SDatabaseEditor +#. Programmer's name for it: SIBDatabaseEditor +#: Vcl/bdeconst.pas:40 +msgid "Da&tabase Editor..." +msgstr "&Datenbank-Editor..." + +#. Programmer's name for it: SExplore +#: Vcl/bdeconst.pas:41 +msgid "E&xplore" +msgstr "E&xplorer" + +#. Programmer's name for it: SLinkDetail +#: Vcl/bdeconst.pas:42 +msgid "'%s' cannot be opened" +msgstr "'%s' kann nicht geöffnet werden" + +#. Programmer's name for it: SLinkMasterSource +#: Vcl/bdeconst.pas:43 +msgid "The MasterSource property of '%s' must be linked to a DataSource" +msgstr "Die MasterSource-Eigenschaft von '%s' muss mit einer DataSource verbunden sein." + +#. Programmer's name for it: SLinkMaster +#: Vcl/bdeconst.pas:44 +msgid "Unable to open the MasterSource Table" +msgstr "MasterSource-Tabelle kann nicht geöffnet werden" + +#. Programmer's name for it: SGQEVerb +#: Vcl/bdeconst.pas:45 +msgid "S&QL Builder..." +msgstr "SQL-&Builder..." + +#. Programmer's name for it: SBindVerb +#: Vcl/bdeconst.pas:46 +msgid "Define &Parameters..." +msgstr "&Parameter definieren..." + +#. Programmer's name for it: SDisconnectDatabase +#: Vcl/bdeconst.pas:48 +msgid "Database is currently connected. Disconnect and continue?" +msgstr "Die Datenbank ist verbunden. Verbindung beenden und weitermachen?" + +#. Programmer's name for it: SBDEError +#: Vcl/bdeconst.pas:49 +msgid "BDE error $%.4x" +msgstr "BDE-Fehler $%.4x" + +#. Programmer's name for it: SLookupSourceError +#: Vcl/bdeconst.pas:50 +msgid "Unable to use duplicate DataSource and LookupSource" +msgstr "Kann doppelte DataSource und LookupSource nicht benutzen" + +#. Programmer's name for it: SLookupTableError +#: Vcl/bdeconst.pas:51 +msgid "LookupSource must be connected to TTable component" +msgstr "LookupSource muss mit TTable-Komponente verbunden werden" + +#. Programmer's name for it: SLookupIndexError +#: Vcl/bdeconst.pas:52 +msgid "%s must be the lookup table's active index" +msgstr "%s muss der aktive Index der Nachschlagetabelle sein." + +#. Programmer's name for it: SParameterTypes +#: Vcl/bdeconst.pas:53 +msgid ";Input;Output;Input/Output;Result" +msgstr ";Eingabe;Ausgabe;Eingabe/Ausgabe;Ergebnis" + +#. Programmer's name for it: SInvalidParamFieldType +#: Vcl/bdeconst.pas:54 +msgid "Must have a valid field type selected" +msgstr "Sie müssen einen gültigen Feldtypen auswählen" + +#. Programmer's name for it: STruncationError +#: Vcl/bdeconst.pas:55 +msgid "Parameter '%s' truncated on output" +msgstr "Parameter '%s' wurde bei Ausgabe abgeschnitten" + +#. Programmer's name for it: SDataTypes +#: Vcl/bdeconst.pas:56 +msgid ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" +msgstr ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" + +#. Programmer's name for it: SResultName +#: Vcl/bdeconst.pas:57 +msgid "Result" +msgstr "Ergebnis" + +#. Programmer's name for it: SDBCaption +#: Vcl/bdeconst.pas:58 +msgid "%s%s%s Database" +msgstr "%s%s%s Datenbanken" + +#. Programmer's name for it: SParamEditor +#: Vcl/bdeconst.pas:59 +msgid "%s%s%s Parameters" +msgstr "%s%s%s Parameter" + +#. Programmer's name for it: SIndexFilesEditor +#: Vcl/bdeconst.pas:60 +msgid "%s%s%s Index Files" +msgstr "%s%s%s Indexdateien" + +#. Programmer's name for it: SNoIndexFiles +#. Programmer's name for it: srNone +#: Vcl/bdeconst.pas:61 +msgid "(None)" +msgstr "(Ohne)" + +#. Programmer's name for it: SIndexDoesNotExist +#: Vcl/bdeconst.pas:62 +msgid "Index does not exist. Index: %s" +msgstr "Index existiert nicht. Index: %s" + +#. Programmer's name for it: SNoTableName +#: Vcl/bdeconst.pas:63 +msgid "Missing TableName property" +msgstr "Eigenschaft TableName fehlt" + +#. Programmer's name for it: SNoDataSetField +#: Vcl/bdeconst.pas:64 +msgid "Missing DataSetField property" +msgstr "Eigenschaft DataSetField fehlt" + +#. Programmer's name for it: SBatchExecute +#. Programmer's name for it: SExecute +#: Vcl/bdeconst.pas:65 +msgid "E&xecute" +msgstr "&Ausführen" + +#. Programmer's name for it: SNoCachedUpdates +#: Vcl/bdeconst.pas:66 +msgid "Not in cached update mode" +msgstr "Nicht im Cached-Update-Modus" + +#. Programmer's name for it: SInvalidAliasName +#: Vcl/bdeconst.pas:67 +msgid "Invalid alias name %s" +msgstr "Ungültiger Aliasname %s" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/bdeconst.pas:68 +msgid "Cannot access field '%s' in a filter" +msgstr "Auf Feld '%s' kann in einem Filter nicht zugegriffen werden" + +#. Programmer's name for it: SUpdateSQLEditor +#. Programmer's name for it: SIBUpdateSQLEditor +#: Vcl/bdeconst.pas:69 +msgid "&UpdateSQL Editor..." +msgstr "UpdateS&QL-Editor..." + +#. Programmer's name for it: SNoDataSet +#: Vcl/bdeconst.pas:70 +msgid "No dataset association" +msgstr "Keine Datenmengenverknüpfung" + +#. Programmer's name for it: SUntitled +#: Vcl/bdeconst.pas:71 +msgid "Untitled Application" +msgstr "Unbenannte Anwendung" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/bdeconst.pas:72 +msgid "Cannot update, %s is not owned by %s" +msgstr "Aktualisierung nicht möglich, %s gehört zu %s" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/bdeconst.pas:73 +msgid "Update failed" +msgstr "Aktualisierung misslungen" + +#. Programmer's name for it: SSQLGenSelect +#: Vcl/bdeconst.pas:74 +msgid "Must select at least one key field and one update field" +msgstr "Sie müssen mindestens ein Schlüsselfeld und ein Updatefeld auswählen" + +#. Programmer's name for it: SSQLNotGenerated +#: Vcl/bdeconst.pas:75 +msgid "Update SQL statements not generated, exit anyway?" +msgstr "Aktualisierungs-SQL-Anweisungen nicht generiert; trotzdem beenden" + +#. Programmer's name for it: SSQLDataSetOpen +#: Vcl/bdeconst.pas:76 +msgid "Unable to determine field names for %s" +msgstr "Die Feldnamen für %s konnten nicht erkannt werden" + +#. Programmer's name for it: SLocalTransDirty +#: Vcl/bdeconst.pas:77 +msgid "The transaction isolation level must be dirty read for local databases" +msgstr "Die Isolationsebene für Transaktionen muss für lokale Datenbanken Dirty-Read sein." + +#. Programmer's name for it: SMissingDataSet +#: Vcl/bdeconst.pas:78 +msgid "Missing DataSet property" +msgstr "Eigenschaft DataSet fehlt" + +#. Programmer's name for it: SNoProvider +#: Vcl/bdeconst.pas:79 +msgid "No provider available" +msgstr "Kein Provider verfügbar" + +#. Programmer's name for it: SNotAQuery +#: Vcl/bdeconst.pas:80 +msgid "Dataset is not a query" +msgstr "Die Datenmenge ist keine Abfrage" + +#. Programmer's name for it: sTabFailClear +#: Vcl/comstrs.pas:15 +msgid "Failed to clear tab control" +msgstr "Register-Element konnte nicht geleert werden" + +#. Programmer's name for it: sTabFailDelete +#: Vcl/comstrs.pas:16 +msgid "Failed to delete tab at index %d" +msgstr "Registerseite mit Index %d konnte nicht gelöscht werden" + +#. Programmer's name for it: sTabFailRetrieve +#: Vcl/comstrs.pas:17 +msgid "Failed to retrieve tab at index %d" +msgstr "Registerseite mit Index %d konnte nicht gelesen werden" + +#. Programmer's name for it: sTabFailGetObject +#: Vcl/comstrs.pas:18 +msgid "Failed to get object at index %d" +msgstr "Objekt mit Index %d konnte nicht gelesen werden" + +#. Programmer's name for it: sTabFailSet +#: Vcl/comstrs.pas:19 +msgid "Failed to set tab \"%s\" at index %d" +msgstr "Registerseite '%s' mit Index %d konnte nicht gesetzt werden" + +#. Programmer's name for it: sTabFailSetObject +#: Vcl/comstrs.pas:20 +msgid "Failed to set object at index %d" +msgstr "Objekt mit Index %d konnte nicht gesetzt werden" + +#. Programmer's name for it: sTabMustBeMultiLine +#: Vcl/comstrs.pas:21 +msgid "MultiLine must be True when TabPosition is tpLeft or tpRight" +msgstr "Bei TabPosition tpLeft und tpRight muß MultiLine True sein" + +#. Programmer's name for it: sInvalidLevel +#: Vcl/comstrs.pas:23 +msgid "Invalid item level assignment" +msgstr "Ungültige Zuweisung von Eintragsebenen" + +#. Programmer's name for it: sInvalidLevelEx +#: Vcl/comstrs.pas:24 +msgid "Invalid level (%d) for item \"%s\"" +msgstr "Ungültige Ebene (%d) für Eintrag \"%s\"" + +#. Programmer's name for it: sInvalidIndex +#: Vcl/comstrs.pas:25 +msgid "Invalid index" +msgstr "Ungültiger Index" + +#. Programmer's name for it: sInsertError +#: Vcl/comstrs.pas:26 +msgid "Unable to insert an item" +msgstr "Eintrag kann nicht eingefügt werden" + +#. Programmer's name for it: sInvalidOwner +#: Vcl/comstrs.pas:28 +msgid "Invalid owner" +msgstr "Ungültiger Besitzer" + +#. Programmer's name for it: sUnableToCreateColumn +#: Vcl/comstrs.pas:29 +msgid "Unable to create new column" +msgstr "Eine neue Spalte kann nicht erzeugt werden" + +#. Programmer's name for it: sUnableToCreateItem +#: Vcl/comstrs.pas:30 +msgid "Unable to create new item" +msgstr "Ein neuer Eintrag kann nicht erzeugt werden" + +#. Programmer's name for it: sRichEditInsertError +#: Vcl/comstrs.pas:32 +msgid "RichEdit line insertion error" +msgstr "Fehler bei Einfügen von RichEdit-Zeile" + +#. Programmer's name for it: sRichEditLoadFail +#: Vcl/comstrs.pas:33 +msgid "Failed to Load Stream" +msgstr "Das Laden des Streams ist mißlungen" + +#. Programmer's name for it: sRichEditSaveFail +#: Vcl/comstrs.pas:34 +msgid "Failed to Save Stream" +msgstr "Das Speichern des Streams ist mißlungen" + +#. Programmer's name for it: sTooManyPanels +#: Vcl/comstrs.pas:36 +msgid "StatusBar cannot have more than 64 panels" +msgstr "StatusBar kann nicht mehr als 64 Bedienfelder (Panels) haben" + +#. Programmer's name for it: sHKError +#: Vcl/comstrs.pas:38 +msgid "Error assigning Hot-Key to %s. %s" +msgstr "Fehler bei der Zuordnung des Tastenkürzels zu %s. %s" + +#. Programmer's name for it: sHKInvalid +#: Vcl/comstrs.pas:39 +msgid "Hot-Key is invalid" +msgstr "Tastenkürzel ist ungültig" + +#. Programmer's name for it: sHKInvalidWindow +#: Vcl/comstrs.pas:40 +msgid "Window is invalid or a child window" +msgstr "Fenster ist ungültig oder ein untergeordnetes Fenster" + +#. Programmer's name for it: sHKAssigned +#: Vcl/comstrs.pas:41 +msgid "Hot-Key is assigned to another window" +msgstr "Tastenkürzel ist einem anderen Fenster zugeordnet" + +#. Programmer's name for it: sUDAssociated +#: Vcl/comstrs.pas:43 +msgid "%s is already associated with %s" +msgstr "%s ist bereits mit %s verknüpft" + +#. Programmer's name for it: sPageIndexError +#: Vcl/comstrs.pas:46 +msgid "%d is an invalid PageIndex value. PageIndex must be between 0 and %d" +msgstr "%d ist ein ungültiger Wert für PageIndex. PageIndex muß einen Wert zwischen 0 und %d besitzen" + +#. Programmer's name for it: sInvalidComCtl32 +#: Vcl/comstrs.pas:48 +msgid "This control requires version 4.70 or greater of COMCTL32.DLL" +msgstr "Dieses Element benötigt COMCTL32.DLL in der Version 4.70 oder höher" + +#. Programmer's name for it: sDateTimeMax +#: Vcl/comstrs.pas:50 +msgid "Date exceeds maximum of %s" +msgstr "Das Datum überschreitet das Maximum von %s" + +#. Programmer's name for it: sDateTimeMin +#: Vcl/comstrs.pas:51 +msgid "Date is less than minimum of %s" +msgstr "Das Datum unterschreitet das Minimum von %s" + +#. Programmer's name for it: sNeedAllowNone +#: Vcl/comstrs.pas:52 +msgid "You must be in ShowCheckbox mode to set to this date" +msgstr "Um das Datum zu setzen, müssen Sie im Modus ShowCheckbox sein" + +#. Programmer's name for it: sFailSetCalDateTime +#: Vcl/comstrs.pas:53 +msgid "Failed to set calendar date or time" +msgstr "Kalenderzeit oder -datum konnte nicht gesetzt werden" + +#. Programmer's name for it: sFailSetCalMaxSelRange +#: Vcl/comstrs.pas:54 +msgid "Failed to set maximum selection range" +msgstr "Der max. Auswahlbereich konnte nicht gesetzt werden" + +#. Programmer's name for it: sFailSetCalMinMaxRange +#: Vcl/comstrs.pas:55 +msgid "Failed to set calendar min/max range" +msgstr "Der max./min. Bereich des Kalenders konnte nicht gesetzt werden" + +#. Programmer's name for it: sCalRangeNeedsMultiSelect +#: Vcl/comstrs.pas:56 +msgid "Date range can only be used in multiselect mode" +msgstr "Datumsbereich kann nur im Multiselect-Modus gebraucht werden" + +#. Programmer's name for it: sFailsetCalSelRange +#: Vcl/comstrs.pas:57 +msgid "Failed to set calendar selected range" +msgstr "Der ausgewählte Bereich des Kalenders kann nicht gesetzt werden" + +#. Programmer's name for it: SOpenFileTitle +#. IndexFiles..OpenDialog..Title +#: Vcl/consts.pas:15 +msgid "Open" +msgstr "Öffnen" + +#. Programmer's name for it: SAssignError +#: Vcl/consts.pas:16 +msgid "Cannot assign a %s to a %s" +msgstr "%s kann nicht zu %s zugewiesen werden" + +#. Programmer's name for it: SFCreateError +#: Vcl/consts.pas:17 +msgid "Cannot create file %s" +msgstr "Datei %s kann nicht erstellt werden" + +#. Programmer's name for it: SFOpenError +#: Vcl/consts.pas:18 +msgid "Cannot open file %s" +msgstr "Datei %s kann nicht geöffnet werden" + +#. Programmer's name for it: SReadError +#: Vcl/consts.pas:19 +msgid "Stream read error" +msgstr "Stream-Lesefehler" + +#. Programmer's name for it: SWriteError +#: Vcl/consts.pas:20 +msgid "Stream write error" +msgstr "Stream-Schreibfehler" + +#. Programmer's name for it: SMemoryStreamError +#: Vcl/consts.pas:21 +msgid "Out of memory while expanding memory stream" +msgstr "Expandieren des Speicher-Stream wegen Speichermangel nicht möglich" + +#. Programmer's name for it: SCantWriteResourceStreamError +#: Vcl/consts.pas:22 +msgid "Can't write to a read-only resource stream" +msgstr "In einen zum Lesen geöffneten Ressourcen-Stream kann nicht geschrieben werden" + +#. Programmer's name for it: SDuplicateReference +#: Vcl/consts.pas:23 +msgid "WriteObject called twice for the same instance" +msgstr "Zweimaliger Aufruf von WriteObject für die gleiche Instanz" + +#. Programmer's name for it: SClassNotFound +#: Vcl/consts.pas:24 +msgid "Class %s not found" +msgstr "Klasse %s nicht gefunden" + +#. Programmer's name for it: SInvalidImage +#. Programmer's name for it: SInvalidStreamFormat +#: Vcl/consts.pas:25 +msgid "Invalid stream format" +msgstr "Ungültiges Stream-Format" + +#. Programmer's name for it: SResNotFound +#. Programmer's name for it: sResNotFound +#: Vcl/consts.pas:26 +msgid "Resource %s not found" +msgstr "Ressource %s wurde nicht gefunden" + +#. Programmer's name for it: SClassMismatch +#: Vcl/consts.pas:27 +msgid "Resource %s is of incorrect class" +msgstr "Ressource %s hat die falsche Klasse" + +#. Programmer's name for it: SListIndexError +#: Vcl/consts.pas:28 +msgid "List index out of bounds (%d)" +msgstr "Listenindex überschreitet das Maximum (%d)" + +#. Programmer's name for it: SListCapacityError +#: Vcl/consts.pas:29 +msgid "List capacity out of bounds (%d)" +msgstr "Kapazität der Liste ist erschöpft (%d)" + +#. Programmer's name for it: SListCountError +#: Vcl/consts.pas:30 +msgid "List count out of bounds (%d)" +msgstr "Zu viele Einträge in der Liste (%d)" + +#. Programmer's name for it: SSortedListError +#: Vcl/consts.pas:31 +msgid "Operation not allowed on sorted string list" +msgstr "Operation bei sortierten Stringlisten nicht erlaubt" + +#. Programmer's name for it: SDuplicateString +#: Vcl/consts.pas:32 +msgid "String list does not allow duplicates" +msgstr "In der Stringliste sind Duplikate nicht erlaubt" + +#. Programmer's name for it: SInvalidTabIndex +#: Vcl/consts.pas:33 +msgid "Tab index out of bounds" +msgstr "Registerindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SInvalidTabPosition +#: Vcl/consts.pas:34 +msgid "Tab position incompatible with current tab style" +msgstr "Die Position des Register ist nicht mit dem aktuellen Erscheinungsbild kompatibel." + +#. Programmer's name for it: SInvalidTabStyle +#: Vcl/consts.pas:35 +msgid "Tab style incompatible with current tab position" +msgstr "Das Erscheinungsbild des Registers ist nicht mit der aktuellen Position kompatibel." + +#. Programmer's name for it: SDuplicateName +#: Vcl/consts.pas:36 +msgid "A component named %s already exists" +msgstr "Komponente mit der Bezeichnung %s existiert bereits" + +#. Programmer's name for it: SInvalidName +#: Vcl/consts.pas:37 +msgid "''%s'' is not a valid component name" +msgstr "''%s'' ist kein gültiger Komponentenname" + +#. Programmer's name for it: SDuplicateClass +#: Vcl/consts.pas:38 +msgid "A class named %s already exists" +msgstr "Klasse mit der Bezeichnung %s existiert bereits" + +#. Programmer's name for it: SNoComSupport +#: Vcl/consts.pas:39 +msgid "%s has not been registered as a COM class" +msgstr "%s wurde nicht als COM-Klasse registriert" + +#. Programmer's name for it: SInvalidInteger +#: Vcl/consts.pas:40 +msgid "''%s'' is not a valid integer value" +msgstr "''%s'' ist kein gültiger Integer-Wert" + +#. Programmer's name for it: SLineTooLong +#. Programmer's name for it: SOutlineLongLine +#: Vcl/consts.pas:41 +msgid "Line too long" +msgstr "Zeile zu lang" + +#. Programmer's name for it: SInvalidPropertyValue +#. Programmer's name for it: SInvalidProperty +#: Vcl/consts.pas:42 +msgid "Invalid property value" +msgstr "Ungültiger Eigenschaftswert" + +#. Programmer's name for it: SInvalidPropertyPath +#: Vcl/consts.pas:43 +msgid "Invalid property path" +msgstr "Ungültiger Pfad für Eigenschaft" + +#. Programmer's name for it: SInvalidPropertyType +#: Vcl/consts.pas:44 +msgid "Invalid property type: %s" +msgstr "Ungültiger Eigenschaftstyp: %s" + +#. Programmer's name for it: SInvalidPropertyElement +#: Vcl/consts.pas:45 +msgid "Invalid property element: %s" +msgstr "Ungültiges Eigenschaftselement: %s" + +#. Programmer's name for it: SUnknownProperty +#: Vcl/consts.pas:46 +msgid "Property does not exist" +msgstr "Eigenschaft existiert nicht" + +#. Programmer's name for it: SReadOnlyProperty +#: Vcl/consts.pas:47 +msgid "Property is read-only" +msgstr "Eigenschaft kann nur gelesen werden" + +#. Programmer's name for it: SPropertyException +#: Vcl/consts.pas:48 +msgid "Error reading %s%s%s: %s" +msgstr "Fehler beim Lesen von %s%s%s: %s" + +#. Programmer's name for it: SAncestorNotFound +#: Vcl/consts.pas:49 +msgid "Ancestor for '%s' not found" +msgstr "Vorfahr für '%s' nicht gefunden" + +#. Programmer's name for it: SInvalidBitmap +#: Vcl/consts.pas:50 +msgid "Bitmap image is not valid" +msgstr "Bitmap ist ungültig" + +#. Programmer's name for it: SInvalidIcon +#: Vcl/consts.pas:51 +msgid "Icon image is not valid" +msgstr "Ungültiges Symbol" + +#. Programmer's name for it: SInvalidMetafile +#: Vcl/consts.pas:52 +msgid "Metafile is not valid" +msgstr "Metadatei ist ungültig" + +#. Programmer's name for it: SInvalidPixelFormat +#: Vcl/consts.pas:53 +msgid "Invalid pixel format" +msgstr "Ungültiges Pixelformat" + +#. Programmer's name for it: SBitmapEmpty +#: Vcl/consts.pas:54 +msgid "Bitmap is empty" +msgstr "Bitmap ist leer" + +#. Programmer's name for it: SScanLine +#: Vcl/consts.pas:55 +msgid "Scan line index out of range" +msgstr "Bereichsüberschreitung bei Zeilenindex" + +#. Programmer's name for it: SChangeIconSize +#: Vcl/consts.pas:56 +msgid "Cannot change the size of an icon" +msgstr "Die Größe eines Symbols kann nicht geändert werden" + +#. Programmer's name for it: SOleGraphic +#: Vcl/consts.pas:57 +msgid "Invalid operation on TOleGraphic" +msgstr "Ungültige Operation für TOleGraphic" + +#. Programmer's name for it: SUnknownExtension +#: Vcl/consts.pas:58 +msgid "Unknown picture file extension (.%s)" +msgstr "Unbekannte Bilddateierweiterung (.%s)" + +#. Programmer's name for it: SUnknownClipboardFormat +#: Vcl/consts.pas:59 +msgid "Unsupported clipboard format" +msgstr "Format der Zwischenablage wird nicht unterstützt" + +#. Programmer's name for it: SOutOfResources +#: Vcl/consts.pas:60 +msgid "Out of system resources" +msgstr "Systemressourcen erschöpft." + +#. Programmer's name for it: SNoCanvasHandle +#: Vcl/consts.pas:61 +msgid "Canvas does not allow drawing" +msgstr "Leinwand/Bild erlaubt kein Zeichnen" + +#. Programmer's name for it: SInvalidImageSize +#: Vcl/consts.pas:62 +msgid "Invalid image size" +msgstr "Ungültige Bildgröße" + +#. Programmer's name for it: STooManyImages +#: Vcl/consts.pas:63 +msgid "Too many images" +msgstr "Zu viele Bilder" + +#. Programmer's name for it: SDimsDoNotMatch +#: Vcl/consts.pas:64 +msgid "Image dimensions do not match image list dimensions" +msgstr "Bildgröße und Bildlistengröße stimmen nicht überein" + +#. Programmer's name for it: SInvalidImageList +#: Vcl/consts.pas:65 +msgid "Invalid ImageList" +msgstr "Ungültige ImageList" + +#. Programmer's name for it: SReplaceImage +#: Vcl/consts.pas:66 +msgid "Unable to Replace Image" +msgstr "Bild kann nicht ersetzt werden" + +#. Programmer's name for it: SImageIndexError +#: Vcl/consts.pas:67 +msgid "Invalid ImageList Index" +msgstr "Ungültiger ImageList-Index" + +#. Programmer's name for it: SImageReadFail +#: Vcl/consts.pas:68 +msgid "Failed to read ImageList data from stream" +msgstr "Die ImageList-Daten konnten nicht aus dem Stream gelesen werden" + +#. Programmer's name for it: SImageWriteFail +#: Vcl/consts.pas:69 +msgid "Failed to write ImageList data to stream" +msgstr "Die ImageList-Daten konnten nicht in den Stream geschrieben werden" + +#. Programmer's name for it: SWindowDCError +#: Vcl/consts.pas:70 +msgid "Error creating window device context" +msgstr "Fehler beim Erstellen des Fenster-Gerätekontexts" + +#. Programmer's name for it: SClientNotSet +#: Vcl/consts.pas:71 +msgid "Client of TDrag not initialized" +msgstr "Client von TDrag wurde nicht initialisiert" + +#. Programmer's name for it: SWindowClass +#: Vcl/consts.pas:72 +msgid "Error creating window class" +msgstr "Metadateien" + +#. Programmer's name for it: SWindowCreate +#: Vcl/consts.pas:73 +msgid "Error creating window" +msgstr "Fehler beim Erzeugen eines Fensters" + +#. Programmer's name for it: SCannotFocus +#: Vcl/consts.pas:74 +msgid "Cannot focus a disabled or invisible window" +msgstr "Ein deaktiviertes oder unsichtbares Fenster kann nicht den Fokus erhalten" + +#. Programmer's name for it: SParentRequired +#: Vcl/consts.pas:75 +msgid "Control '%s' has no parent window" +msgstr "Element '%s' hat kein übergeordnetes Fenster" + +#. Programmer's name for it: SMDIChildNotVisible +#: Vcl/consts.pas:76 +msgid "Cannot hide an MDI Child Form" +msgstr "Ein MDI-Kindformular kann nicht verborgen werden" + +#. Programmer's name for it: SVisibleChanged +#: Vcl/consts.pas:77 +msgid "Cannot change Visible in OnShow or OnHide" +msgstr "Eigenschaft Visible kann in OnShow oder OnHide nicht verändert werden" + +#. Programmer's name for it: SCannotShowModal +#: Vcl/consts.pas:78 +msgid "Cannot make a visible window modal" +msgstr "Aus einem sichtbaren Fenster kann kein modales gemacht werden" + +#. Programmer's name for it: SScrollBarRange +#: Vcl/consts.pas:79 +msgid "Scrollbar property out of range" +msgstr "Eigenschaft Scrollbar außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SPropertyOutOfRange +#: Vcl/consts.pas:80 +msgid "%s property out of range" +msgstr "Eigenschaft %s außerhalb des gültigen Bereichs" + +#. Programmer's name for it: SMenuIndexError +#: Vcl/consts.pas:81 +msgid "Menu index out of range" +msgstr "Menüindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SMenuReinserted +#: Vcl/consts.pas:82 +msgid "Menu inserted twice" +msgstr "Menü zweimal eingefügt" + +#. Programmer's name for it: SMenuNotFound +#: Vcl/consts.pas:83 +msgid "Sub-menu is not in menu" +msgstr "Untermenü ist nicht im Menü" + +#. Programmer's name for it: SNoTimers +#: Vcl/consts.pas:84 +msgid "Not enough timers available" +msgstr "Nicht genügend Timer verfügbar" + +#. Programmer's name for it: SNotPrinting +#: Vcl/consts.pas:85 +msgid "Printer is not currently printing" +msgstr "Der Drucker druckt aktuell nicht" + +#. Programmer's name for it: SPrinting +#: Vcl/consts.pas:86 +msgid "Printing in progress" +msgstr "Druckvorgang läuft" + +#. Programmer's name for it: SPrinterIndexError +#: Vcl/consts.pas:87 +msgid "Printer index out of range" +msgstr "Druckerindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SInvalidPrinter +#: Vcl/consts.pas:88 +msgid "Printer selected is not valid" +msgstr "Ausgewählter Drucker ist ungültig" + +#. Programmer's name for it: SDeviceOnPort +#: Vcl/consts.pas:89 +msgid "%s on %s" +msgstr "%s an %s" + +#. Programmer's name for it: SGroupIndexTooLow +#: Vcl/consts.pas:90 +msgid "GroupIndex cannot be less than a previous menu item's GroupIndex" +msgstr "GroupIndex kann nicht kleiner sein als der GroupIndex eines vorhergehenden Menüelementes" + +#. Programmer's name for it: STwoMDIForms +#: Vcl/consts.pas:91 +msgid "Cannot have more than one MDI form per application" +msgstr "Es ist nur ein MDI-Formular pro Anwendung möglich" + +#. Programmer's name for it: SNoMDIForm +#: Vcl/consts.pas:92 +msgid "Cannot create form. No MDI forms are currently active" +msgstr "Formular kann nicht erstellt werden. Zur Zeit sind keine MDI-Formulare aktiv" + +#. Programmer's name for it: SRegisterError +#: Vcl/consts.pas:93 +msgid "Invalid component registration" +msgstr "Ungültige Komponentenregistrierung" + +#. Programmer's name for it: SImageCanvasNeedsBitmap +#: Vcl/consts.pas:94 +msgid "Can only modify an image if it contains a bitmap" +msgstr "Ein Bild kann nur geändert werden, wenn es ein Bitmap enthält" + +#. Programmer's name for it: SControlParentSetToSelf +#: Vcl/consts.pas:95 +msgid "A control cannot have itself as its parent" +msgstr "Ein Steuerelement kann nicht sich selbst als Vorfahr haben" + +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#. DSSCubeEditor..OKButton..Caption +#. DSSQueryEditor..OKButton..Caption +#. ConnEditForm..OkButton..Caption +#. ClientDataForm..OkBtn..Caption +#. DBEditForm..OkButton..Caption +#. AddFields..OkBtn..Caption +#. AssociateAttributes..OKBtn..Caption +#. SaveAttributesAs..OKBtn..Caption +#. DefineField..OkBtn..Caption +#. LinkFields..Button1..Caption +#. IndexFiles..Ok..Caption +#. PictureEditorDlg..OKButton..Caption +#: Vcl/consts.pas:96 +#: Cube/mxdssqry.dfm:321 +#: Property Editors/adoconed.dfm:19 +#: Editors/cdsedit.dfm:39 +#: Editors/dbedit.dfm:140 +#: Editors/dsadd.dfm:24 +#: Editors/dsattra.dfm:18 +#: Editors/dsattrs.dfm:56 +#: Editors/dsdefine.dfm:103 +#: Editors/fldlinks.dfm:141 +#: Editors/ixedit.dfm:64 +#: Editors/picedit.dfm:22 +msgid "OK" +msgstr "OK" + +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#. DSSCubeEditor..CancelButton..Caption +#. DSSQueryEditor..Cancel..Caption +#. ConnEditForm..CancelButton..Caption +#. ClientDataForm..CancelBtn..Caption +#. DBEditForm..CancelButton..Caption +#. InputReqDialog..CancelButton..Caption +#. LoginDialog..CancelButton..Caption +#. AddFields..CancelBtn..Caption +#. AssociateAttributes..CancelBtn..Caption +#. SaveAttributesAs..CancelBtn..Caption +#. DefineField..CancelBtn..Caption +#. LinkFields..Button2..Caption +#. IndexFiles..Cancel..Caption +#. PictureEditorDlg..CancelButton..Caption +#. SQLEditForm..ButtonPanel..CancelButton..Caption +#. StrEditDlg..CancelButton..Caption +#. UpdateSQLEditForm..CancelButton..Caption +#: Vcl/consts.pas:97 +#: Cube/mxdssqry.dfm:311 +#: Property Editors/adoconed.dfm:30 +#: Editors/cdsedit.dfm:52 +#: Editors/dbedit.dfm:152 +#: Editors/dbinpreq.dfm:29 +#: Editors/dblogdlg.dfm:30 +#: Editors/dsadd.dfm:36 +#: Editors/dsattra.dfm:30 +#: Editors/dsattrs.dfm:67 +#: Editors/dsdefine.dfm:115 +#: Editors/fldlinks.dfm:153 +#: Editors/ixedit.dfm:75 +#: Editors/picedit.dfm:33 +#: Editors/sqledit.dfm:106 +#: Editors/stredit.dfm:66 +#: Editors/updsqled.dfm:32 +msgid "Cancel" +msgstr "Abbrechen" + +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#: Vcl/consts.pas:98 +msgid "&Yes" +msgstr "&Ja" + +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#: Vcl/consts.pas:99 +msgid "&No" +msgstr "&Nein" + +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#. DSSCubeEditor..HelpButton..Caption +#. DSSQueryEditor..HelpButton..Caption +#. ConnEditForm..HelpButton..Caption +#. ClientDataForm..HelpBtn..Caption +#. DBEditForm..HelpButton..Caption +#. DataBindForm..HelpBtn..Caption +#. AddFields..HelpBtn..Caption +#. AssociateAttributes..HelpBtn..Caption +#. SaveAttributesAs..HelpBtn..Caption +#. DefineField..HelpBtn..Caption +#. LinkFields..Help..Caption +#. IndexFiles..Help..Caption +#. PictureEditorDlg..HelpButton..Caption +#. SQLEditForm..ButtonPanel..HelpButton..Caption +#. StrEditDlg..HelpButton..Caption +#. UpdateSQLEditForm..HelpButton..Caption +#: Vcl/consts.pas:100 +#: Cube/mxdssqry.dfm:331 +#: Property Editors/adoconed.dfm:39 +#: Editors/cdsedit.dfm:61 +#: Editors/dbedit.dfm:161 +#: Editors/dboleedt.dfm:128 +#: Editors/dsadd.dfm:65 +#: Editors/dsattra.dfm:40 +#: Editors/dsattrs.dfm:77 +#: Editors/dsdefine.dfm:124 +#: Editors/fldlinks.dfm:162 +#: Editors/ixedit.dfm:84 +#: Editors/picedit.dfm:42 +#: Editors/sqledit.dfm:116 +#: Editors/stredit.dfm:46 +#: Editors/updsqled.dfm:41 +msgid "&Help" +msgstr "&Hilfe" + +#. Programmer's name for it: SCloseButton +#. SocketForm..PopupMenu..miClose..Caption +#: Vcl/consts.pas:101 +msgid "&Close" +msgstr "S&chließen" + +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#: Vcl/consts.pas:102 +msgid "&Ignore" +msgstr "&Ignorieren" + +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#: Vcl/consts.pas:103 +msgid "&Retry" +msgstr "&Wiederholen" + +#. Programmer's name for it: SAbortButton +#: Vcl/consts.pas:104 +msgid "Abort" +msgstr "Abbrechen" + +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#: Vcl/consts.pas:105 +msgid "&All" +msgstr "&Alle" + +#. Programmer's name for it: SCannotDragForm +#: Vcl/consts.pas:107 +msgid "Cannot drag a form" +msgstr "Formulare können nicht gezogen werden" + +#. Programmer's name for it: SPutObjectError +#: Vcl/consts.pas:108 +msgid "PutObject to undefined item" +msgstr "PutObject auf undefiniertes Element" + +#. Programmer's name for it: SCardDLLNotLoaded +#: Vcl/consts.pas:109 +msgid "Could not load CARDS.DLL" +msgstr "CARDS.DLL kann nicht geladen werden" + +#. Programmer's name for it: SDuplicateCardId +#: Vcl/consts.pas:110 +msgid "Duplicate CardId found" +msgstr "Doppelte CardId gefunden" + +#. Programmer's name for it: SDdeErr +#: Vcl/consts.pas:112 +msgid "An error returned from DDE ($0%x)" +msgstr "Vom DDE wurde ein Fehler zurückgegeben ($0%x)" + +#. Programmer's name for it: SDdeConvErr +#: Vcl/consts.pas:113 +msgid "DDE Error - conversation not established ($0%x)" +msgstr "DDE-Fehler - Konversation konnte nicht etabliert werden ($0%x)" + +#. Programmer's name for it: SDdeMemErr +#: Vcl/consts.pas:114 +msgid "Error occurred when DDE ran out of memory ($0%x)" +msgstr "Wegen Speichermangel bei DDE ist ein Fehler aufgetreten ($0%x)." + +#. Programmer's name for it: SDdeNoConnect +#: Vcl/consts.pas:115 +msgid "Unable to connect DDE conversation" +msgstr "DDE-Konversation konnte nicht verbunden werden." + +#. Programmer's name for it: SFB +#: Vcl/consts.pas:117 +msgid "FB" +msgstr "VH" + +#. Programmer's name for it: SFG +#: Vcl/consts.pas:118 +msgid "FG" +msgstr "VG" + +#. Programmer's name for it: SBG +#: Vcl/consts.pas:119 +msgid "BG" +msgstr "HG" + +#. Programmer's name for it: SOldTShape +#: Vcl/consts.pas:120 +msgid "Cannot load older version of TShape" +msgstr "Kann ältere Version von TShape nicht laden" + +#. Programmer's name for it: SVMetafiles +#: Vcl/consts.pas:121 +msgid "Metafiles" +msgstr "Metadateien" + +#. Programmer's name for it: SVEnhMetafiles +#: Vcl/consts.pas:122 +msgid "Enhanced Metafiles" +msgstr "Erweiterte Metadateien" + +#. Programmer's name for it: SVIcons +#: Vcl/consts.pas:123 +msgid "Icons" +msgstr "Symbole" + +#. Programmer's name for it: SVBitmaps +#: Vcl/consts.pas:124 +msgid "Bitmaps" +msgstr "Bitmaps" + +#. Programmer's name for it: SGridTooLarge +#: Vcl/consts.pas:125 +msgid "Grid too large for operation" +msgstr "Gitter zu groß für Operation" + +#. Programmer's name for it: STooManyDeleted +#: Vcl/consts.pas:126 +msgid "Too many rows or columns deleted" +msgstr "Zu viele Zeilen oder Spalten gelöscht" + +#. Programmer's name for it: SIndexOutOfRange +#: Vcl/consts.pas:127 +msgid "Grid index out of range" +msgstr "Gitterindex außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SFixedColTooBig +#: Vcl/consts.pas:128 +msgid "Fixed column count must be less than column count" +msgstr "Die Anzahl fester Spalten muss kleiner sein als die Spaltenanzahl" + +#. Programmer's name for it: SFixedRowTooBig +#: Vcl/consts.pas:129 +msgid "Fixed row count must be less than row count" +msgstr "Die Anzahl fester Zeilen muss kleiner sein als die Zeilenanzahl" + +#. Programmer's name for it: SInvalidStringGridOp +#: Vcl/consts.pas:130 +msgid "Cannot insert or delete rows from grid" +msgstr "Es können keine Zeilen des Tabellengitters gelöscht oder eingefügt werden" + +#. Programmer's name for it: SParseError +#: Vcl/consts.pas:131 +msgid "%s on line %d" +msgstr "%s in Zeile %d" + +#. Programmer's name for it: SIdentifierExpected +#: Vcl/consts.pas:132 +msgid "Identifier expected" +msgstr "Bezeichner erwartet" + +#. Programmer's name for it: SStringExpected +#: Vcl/consts.pas:133 +msgid "String expected" +msgstr "String erwartet" + +#. Programmer's name for it: SNumberExpected +#: Vcl/consts.pas:134 +msgid "Number expected" +msgstr "Zahl erwartet" + +#. Programmer's name for it: SCharExpected +#: Vcl/consts.pas:135 +msgid "''%s'' expected" +msgstr "''%s'' erwartet" + +#. Programmer's name for it: SSymbolExpected +#: Vcl/consts.pas:136 +msgid "%s expected" +msgstr "%s erwartet" + +#. Programmer's name for it: SInvalidNumber +#: Vcl/consts.pas:137 +msgid "Invalid numeric value" +msgstr "Ungültiger numerischer Wert" + +#. Programmer's name for it: SInvalidString +#: Vcl/consts.pas:138 +msgid "Invalid string constant" +msgstr "Ungültige Stringkonstante" + +#. Programmer's name for it: SInvalidBinary +#: Vcl/consts.pas:140 +msgid "Invalid binary value" +msgstr "Ungültiger Binärwert" + +#. Programmer's name for it: SOutlineIndexError +#: Vcl/consts.pas:141 +msgid "Outline index not found" +msgstr "Gliederungsindex nicht gefunden" + +#. Programmer's name for it: SOutlineExpandError +#: Vcl/consts.pas:142 +msgid "Parent must be expanded" +msgstr "Elternknoten muß expandiert sein" + +#. Programmer's name for it: SInvalidCurrentItem +#: Vcl/consts.pas:143 +msgid "Invalid value for current item" +msgstr "Ungültiger Wert" + +#. Programmer's name for it: SMaskErr +#: Vcl/consts.pas:144 +msgid "Invalid input value" +msgstr "Ungültiger Eingabewert" + +#. Programmer's name for it: SMaskEditErr +#: Vcl/consts.pas:145 +msgid "Invalid input value. Use escape key to abandon changes" +msgstr "Ungültiger Eingabewert. Mit der Taste ESC machen Sie die Änderungen rückgängig." + +#. Programmer's name for it: SOutlineError +#: Vcl/consts.pas:146 +msgid "Invalid outline index" +msgstr "Ungültiger Gliederungsindex" + +#. Programmer's name for it: SOutlineBadLevel +#: Vcl/consts.pas:147 +msgid "Incorrect level assignment" +msgstr "Ungültige Zuweisung von Ebenen" + +#. Programmer's name for it: SOutlineSelection +#: Vcl/consts.pas:148 +msgid "Invalid selection" +msgstr "Ungültige Auswahl" + +#. Programmer's name for it: SOutlineFileLoad +#: Vcl/consts.pas:149 +msgid "File load error" +msgstr "Fehler beim Dateiladen" + +#. Programmer's name for it: SOutlineMaxLevels +#: Vcl/consts.pas:151 +msgid "Maximum outline depth exceeded" +msgstr "Maximale Gliederungstiefe überschritten" + +#. Programmer's name for it: SMsgDlgWarning +#: Vcl/consts.pas:153 +msgid "Warning" +msgstr "Warnung" + +#. Programmer's name for it: SMsgDlgError +#: Vcl/consts.pas:154 +msgid "Error" +msgstr "Fehler" + +#. Programmer's name for it: SMsgDlgInformation +#: Vcl/consts.pas:155 +msgid "Information" +msgstr "Information" + +#. Programmer's name for it: SMsgDlgConfirm +#: Vcl/consts.pas:156 +msgid "Confirm" +msgstr "Bestätigung" + +#. Programmer's name for it: SMsgDlgHelpNone +#: Vcl/consts.pas:162 +msgid "No help available" +msgstr "Keine Hilfe verfügbar" + +#. Programmer's name for it: SMsgDlgHelpHelp +#: Vcl/consts.pas:163 +msgid "Help" +msgstr "Hilfe" + +#. Programmer's name for it: SMsgDlgAbort +#: Vcl/consts.pas:164 +msgid "&Abort" +msgstr "&Abbrechen" + +#. Programmer's name for it: SMsgDlgNoToAll +#: Vcl/consts.pas:168 +msgid "N&o to All" +msgstr "&Alle Nein" + +#. Programmer's name for it: SMsgDlgYesToAll +#: Vcl/consts.pas:169 +msgid "Yes to &All" +msgstr "A&lle Ja" + +#. Programmer's name for it: SmkcBkSp +#: Vcl/consts.pas:171 +msgid "BkSp" +msgstr "Rück" + +#. Programmer's name for it: SmkcTab +#: Vcl/consts.pas:172 +msgid "Tab" +msgstr "Tab" + +#. Programmer's name for it: SmkcEsc +#: Vcl/consts.pas:173 +msgid "Esc" +msgstr "Esc" + +#. Programmer's name for it: SmkcEnter +#: Vcl/consts.pas:174 +msgid "Enter" +msgstr "Eingabe" + +#. Programmer's name for it: SmkcSpace +#: Vcl/consts.pas:175 +msgid "Space" +msgstr "Leertaste" + +#. Programmer's name for it: SmkcPgUp +#: Vcl/consts.pas:176 +msgid "PgUp" +msgstr "BildAuf" + +#. Programmer's name for it: SmkcPgDn +#: Vcl/consts.pas:177 +msgid "PgDn" +msgstr "BildAb" + +#. Programmer's name for it: SmkcEnd +#: Vcl/consts.pas:178 +msgid "End" +msgstr "Ende" + +#. Programmer's name for it: SmkcHome +#: Vcl/consts.pas:179 +msgid "Home" +msgstr "Pos1" + +#. Programmer's name for it: SmkcLeft +#: Vcl/consts.pas:180 +msgid "Left" +msgstr "Left" + +#. Programmer's name for it: SmkcUp +#: Vcl/consts.pas:181 +msgid "Up" +msgstr "Nach oben" + +#. Programmer's name for it: SmkcRight +#: Vcl/consts.pas:182 +msgid "Right" +msgstr "Rechts" + +#. Programmer's name for it: SmkcDown +#: Vcl/consts.pas:183 +msgid "Down" +msgstr "Nach unten" + +#. Programmer's name for it: SmkcIns +#: Vcl/consts.pas:184 +msgid "Ins" +msgstr "Einfg" + +#. Programmer's name for it: SmkcDel +#: Vcl/consts.pas:185 +msgid "Del" +msgstr "Entf" + +#. Programmer's name for it: SmkcShift +#: Vcl/consts.pas:186 +msgid "Shift+" +msgstr "Umsch+" + +#. Programmer's name for it: SmkcCtrl +#: Vcl/consts.pas:187 +msgid "Ctrl+" +msgstr "Strg+" + +#. Programmer's name for it: SmkcAlt +#: Vcl/consts.pas:188 +msgid "Alt+" +msgstr "Alt+" + +#. Programmer's name for it: srUnknown +#. Programmer's name for it: SHostUnknown +#: Vcl/consts.pas:190 +msgid "(Unknown)" +msgstr "(Unbekannt)" + +#. Programmer's name for it: SOutOfRange +#: Vcl/consts.pas:192 +msgid "Value must be between %d and %d" +msgstr "Wert muß zwischen %d und %d liegen" + +#. Programmer's name for it: SCannotCreateName +#: Vcl/consts.pas:193 +msgid "Cannot create a default method name for an unnamed component" +msgstr "Für eine unbenannte Komponente kann kein Standard-Methodennamen erstellt werden" + +#. Programmer's name for it: SDateEncodeError +#: Vcl/consts.pas:195 +msgid "Invalid argument to date encode" +msgstr "Ungültiges Argument zum Codieren des Datums" + +#. Programmer's name for it: STimeEncodeError +#: Vcl/consts.pas:196 +msgid "Invalid argument to time encode" +msgstr "Ungültiges Argument zur zeit-Codierung" + +#. Programmer's name for it: SInvalidDate +#: Vcl/consts.pas:197 +msgid "''%s'' is not a valid date" +msgstr "''%s'' ist kein gültiges Datum" + +#. Programmer's name for it: SInvalidTime +#: Vcl/consts.pas:198 +msgid "''%s'' is not a valid time" +msgstr "''%s'' ist keine gültige Zeit" + +#. Programmer's name for it: SInvalidDateTime +#: Vcl/consts.pas:199 +msgid "''%s'' is not a valid date and time" +msgstr "''%s'' ist kein gültiges Datum und Zeit" + +#. Programmer's name for it: SInvalidFileName +#: Vcl/consts.pas:200 +msgid "Invalid file name - %s" +msgstr "Ungültiger Dateiname - %s" + +#. Programmer's name for it: SDefaultFilter +#: Vcl/consts.pas:201 +msgid "All files (*.*)|*.*" +msgstr "Alle Dateien (*.*)|*.*" + +#. Programmer's name for it: sAllFilter +#: Vcl/consts.pas:202 +msgid "All" +msgstr "Alle" + +#. Programmer's name for it: SNoVolumeLabel +#: Vcl/consts.pas:203 +msgid ": [ - no volume label - ]" +msgstr ": [ - Ohne Namen - ]" + +#. Programmer's name for it: SInsertLineError +#: Vcl/consts.pas:204 +msgid "Unable to insert a line" +msgstr "Zeile kann nicht eingefügt werden" + +#. Programmer's name for it: SConfirmCreateDir +#: Vcl/consts.pas:206 +msgid "The specified directory does not exist. Create it?" +msgstr "Das angegebene Verzeichnis existiert nicht. Soll es angelegt werden?" + +#. Programmer's name for it: SSelectDirCap +#: Vcl/consts.pas:207 +msgid "Select Directory" +msgstr "Verzeichnis auswählen" + +#. Programmer's name for it: SCannotCreateDir +#: Vcl/consts.pas:208 +msgid "Unable to create directory" +msgstr "Verzeichnis kann nicht erstellt werden" + +#. Programmer's name for it: SDirNameCap +#: Vcl/consts.pas:209 +msgid "Directory &Name:" +msgstr "Verzeichnis&name:" + +#. Programmer's name for it: SDrivesCap +#: Vcl/consts.pas:210 +msgid "D&rives:" +msgstr "&Laufwerke:" + +#. Programmer's name for it: SDirsCap +#: Vcl/consts.pas:211 +msgid "&Directories:" +msgstr "&Verzeichnisse:" + +#. Programmer's name for it: SFilesCap +#: Vcl/consts.pas:212 +msgid "&Files: (*.*)" +msgstr "&Dateien: (*.*)" + +#. Programmer's name for it: SNetworkCap +#: Vcl/consts.pas:213 +msgid "Ne&twork..." +msgstr "Ne&tzwerk..." + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:215 +msgid "Color" +msgstr "Farben" + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:216 +msgid "ABCDEFGHIJKLMNOP" +msgstr "ABCDEFGHIJKLMNOP" + +#. Programmer's name for it: SInvalidClipFmt +#: Vcl/consts.pas:218 +msgid "Invalid clipboard format" +msgstr "Ungültiges Format der Zwischenablage" + +#. Programmer's name for it: SIconToClipboard +#: Vcl/consts.pas:219 +msgid "Clipboard does not support Icons" +msgstr "Zwischenablage unterstützt keine Symbole" + +#. Programmer's name for it: SCannotOpenClipboard +#: Vcl/consts.pas:220 +msgid "Cannot open clipboard" +msgstr "Zwischenablage kann nicht geöffnet werden" + +#. Programmer's name for it: SDefault +#. Programmer's name for it: sHTTPItemDefault +#. SQLWindow..DBGrid1..TitleFont.Name +#. DSSQueryEditor..Pager..Dimensions..AddAgg..Font.Name +#: Vcl/consts.pas:222 +#: Cube/mxdssqry.dfm:193 +msgid "Default" +msgstr "Vorgabe" + +#. Programmer's name for it: SInvalidMemoSize +#: Vcl/consts.pas:224 +msgid "Text exceeds memo capacity" +msgstr "Text überschreitet Memo-Kapazität" + +#. Programmer's name for it: SCustomColors +#: Vcl/consts.pas:225 +msgid "Custom Colors" +msgstr "Selbstdefinierte Farben" + +#. Programmer's name for it: SInvalidPrinterOp +#: Vcl/consts.pas:226 +msgid "Operation not supported on selected printer" +msgstr "Operation auf ausgewähltem Drucker nicht verfügbar" + +#. Programmer's name for it: SNoDefaultPrinter +#: Vcl/consts.pas:227 +msgid "There is no default printer currently selected" +msgstr "Zur Zeit ist kein Standard-Drucker gewählt" + +#. Programmer's name for it: SIniFileWriteError +#: Vcl/consts.pas:229 +msgid "Unable to write to %s" +msgstr "In %s kann nicht geschrieben werden" + +#. Programmer's name for it: SBitsIndexError +#: Vcl/consts.pas:231 +msgid "Bits index out of range" +msgstr "Bits-Index außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SUntitled +#: Vcl/consts.pas:233 +msgid "(Untitled)" +msgstr "(Unbenannt)" + +#. Programmer's name for it: SInvalidRegType +#: Vcl/consts.pas:235 +msgid "Invalid data type for '%s'" +msgstr "Ungültiger Datentyp für '%s'" + +#. Programmer's name for it: SRegCreateFailed +#: Vcl/consts.pas:236 +msgid "Failed to create key %s" +msgstr "Erzeugung von Schlüssel %s misslungen" + +#. Programmer's name for it: SRegSetDataFailed +#: Vcl/consts.pas:237 +msgid "Failed to set data for '%s'" +msgstr "Fehler beim Setzen der Daten für '%s'" + +#. Programmer's name for it: SRegGetDataFailed +#: Vcl/consts.pas:238 +msgid "Failed to get data for '%s'" +msgstr "Fehler beim Holen der Daten für '%s'" + +#. Programmer's name for it: SUnknownConversion +#: Vcl/consts.pas:240 +msgid "Unknown RichEdit conversion file extension (.%s)" +msgstr "Unbekannte Dateierweiterung für RichEdit-Konvertierung (.%s)" + +#. Programmer's name for it: SDuplicateMenus +#: Vcl/consts.pas:241 +msgid "Menu '%s' is already being used by another form" +msgstr "Menü '%s' wird bereits von einem anderen Formular benutzt" + +#. Programmer's name for it: SPictureLabel +#: Vcl/consts.pas:243 +msgid "Picture:" +msgstr "Grafik:" + +#. Programmer's name for it: SPictureDesc +#: Vcl/consts.pas:244 +msgid " (%dx%d)" +msgstr " (%dx%d)" + +#. Programmer's name for it: SPreviewLabel +#: Vcl/consts.pas:245 +msgid "Preview" +msgstr "Vorschau" + +#. Programmer's name for it: SCannotOpenAVI +#: Vcl/consts.pas:247 +msgid "Cannot open AVI" +msgstr "AVI kann nicht geöffnet werden" + +#. Programmer's name for it: SNotOpenErr +#: Vcl/consts.pas:249 +msgid "No MCI device open" +msgstr "Kein MCI-Gerät geöffnet" + +#. Programmer's name for it: SMPOpenFilter +#: Vcl/consts.pas:250 +msgid "All files (*.*)|*.*|Wave files (*.wav)|*.wav|Midi files (*.mid)|*.mid|Video for Windows (*.avi)|*.avi" +msgstr "Alle Dateien (*.*)|*.*|Wave-Dateien (*.WAV)|*.WAV|Midi-Dateien (*.MID)|*.MID|Video für Windows (*.avi)|*.avi" + +#. Programmer's name for it: SMCIAVIVideo +#: Vcl/consts.pas:252 +msgid "AVIVideo" +msgstr "AVIVideo" + +#. Programmer's name for it: SMCICDAudio +#: Vcl/consts.pas:253 +msgid "CDAudio" +msgstr "CDAudio" + +#. Programmer's name for it: SMCIDAT +#: Vcl/consts.pas:254 +msgid "DAT" +msgstr "DAT" + +#. Programmer's name for it: SMCIDigitalVideo +#: Vcl/consts.pas:255 +msgid "DigitalVideo" +msgstr "DigitalVideo" + +#. Programmer's name for it: SMCIMMMovie +#: Vcl/consts.pas:256 +msgid "MMMovie" +msgstr "MMMovie" + +#. Programmer's name for it: SMCIOther +#: Vcl/consts.pas:257 +msgid "Other" +msgstr "Andere" + +#. Programmer's name for it: SMCIOverlay +#: Vcl/consts.pas:258 +msgid "Overlay" +msgstr "Überlagert" + +#. Programmer's name for it: SMCIScanner +#: Vcl/consts.pas:259 +msgid "Scanner" +msgstr "Scanner" + +#. Programmer's name for it: SMCISequencer +#: Vcl/consts.pas:260 +msgid "Sequencer" +msgstr "Sequencer" + +#. Programmer's name for it: SMCIVCR +#: Vcl/consts.pas:261 +msgid "VCR" +msgstr "VCR" + +#. Programmer's name for it: SMCIVideodisc +#: Vcl/consts.pas:262 +msgid "Videodisc" +msgstr "Videodisc" + +#. Programmer's name for it: SMCIWaveAudio +#: Vcl/consts.pas:263 +msgid "WaveAudio" +msgstr "WaveAudio" + +#. Programmer's name for it: SMCIUnknownError +#: Vcl/consts.pas:264 +msgid "Unknown error code" +msgstr "Unbekannter Fehler-Code" + +#. Programmer's name for it: SBoldItalicFont +#: Vcl/consts.pas:266 +msgid "Bold Italic" +msgstr "Fett kursiv" + +#. Programmer's name for it: SBoldFont +#: Vcl/consts.pas:267 +msgid "Bold" +msgstr "Fett" + +#. Programmer's name for it: SItalicFont +#: Vcl/consts.pas:268 +msgid "Italic" +msgstr "Kursiv" + +#. Programmer's name for it: SRegularFont +#: Vcl/consts.pas:269 +msgid "Regular" +msgstr "Normal" + +#. Programmer's name for it: SPropertiesVerb +#. SocketForm..Pages..PropPage..Caption +#: Vcl/consts.pas:271 +msgid "Properties" +msgstr "Eigenschaften" + +#. Programmer's name for it: sWindowsSocketError +#: Vcl/consts.pas:273 +msgid "Windows socket error: %s (%d), on API '%s'" +msgstr "Windows-Socket-Fehler: %s (%d), auf API '%s'" + +#. Programmer's name for it: sAsyncSocketError +#: Vcl/consts.pas:274 +msgid "Asynchronous socket error %d" +msgstr "Asynchroner Socket-Fehler %d" + +#. Programmer's name for it: sNoAddress +#: Vcl/consts.pas:275 +msgid "No address specified" +msgstr "Keine Adresse angegeben" + +#. Programmer's name for it: sCannotListenOnOpen +#: Vcl/consts.pas:276 +msgid "Can't listen on an open socket" +msgstr "Offener Socket kann nicht überwacht werden" + +#. Programmer's name for it: sCannotCreateSocket +#: Vcl/consts.pas:277 +msgid "Can't create new socket" +msgstr "Es kann kein neuer Socket erzeugt werden" + +#. Programmer's name for it: sSocketAlreadyOpen +#: Vcl/consts.pas:278 +msgid "Socket already open" +msgstr "Socket ist bereits geöffnet" + +#. Programmer's name for it: sCantChangeWhileActive +#: Vcl/consts.pas:279 +msgid "Can't change value while socket is active" +msgstr "Wert kann nicht geändert werden, während der Socket aktiv ist" + +#. Programmer's name for it: sSocketMustBeBlocking +#: Vcl/consts.pas:280 +msgid "Socket must be in blocking mode" +msgstr "Socket muss sich im Blocking-Modus befinden" + +#. Programmer's name for it: sSocketIOError +#: Vcl/consts.pas:281 +msgid "%s error %d, %s" +msgstr "%s-Fehler %d, %s" + +#. Programmer's name for it: sSocketRead +#. Programmer's name for it: SReadAccess +#: Vcl/consts.pas:282 +msgid "Read" +msgstr "Lesen" + +#. Programmer's name for it: sSocketWrite +#. Programmer's name for it: SWriteAccess +#: Vcl/consts.pas:283 +msgid "Write" +msgstr "Schreiben" + +#. Programmer's name for it: SServiceFailed +#: Vcl/consts.pas:285 +msgid "Service failed on %s: %s" +msgstr "Service fehlgeschlagen bei %s:%s" + +#. Programmer's name for it: SExecute +#: Vcl/consts.pas:286 +msgid "execute" +msgstr "Ausführen" + +#. Programmer's name for it: SStart +#: Vcl/consts.pas:287 +msgid "start" +msgstr "Start" + +#. Programmer's name for it: SStop +#: Vcl/consts.pas:288 +msgid "stop" +msgstr "Stop" + +#. Programmer's name for it: SPause +#: Vcl/consts.pas:289 +msgid "pause" +msgstr "Pause" + +#. Programmer's name for it: SContinue +#: Vcl/consts.pas:290 +msgid "continue" +msgstr "Weiter" + +#. Programmer's name for it: SInterrogate +#: Vcl/consts.pas:291 +msgid "interrogate" +msgstr "Anfragen" + +#. Programmer's name for it: SShutdown +#: Vcl/consts.pas:292 +msgid "shutdown" +msgstr "Herunterfahren" + +#. Programmer's name for it: SCustomError +#: Vcl/consts.pas:293 +msgid "Service failed in custom message(%d): %s" +msgstr "Service fehlgeschlagen in selbstdef. Meldung (%d): %s" + +#. Programmer's name for it: SServiceInstallOK +#: Vcl/consts.pas:294 +msgid "Service installed successfully" +msgstr "Service erfolgreich installiert" + +#. Programmer's name for it: SServiceInstallFailed +#: Vcl/consts.pas:295 +msgid "Service \"%s\" failed to install with error: \"%s\"" +msgstr "Service \"%s\" konnte nicht installiert werden; Fehler: \"%s\"" + +#. Programmer's name for it: SServiceUninstallOK +#: Vcl/consts.pas:296 +msgid "Service uninstalled successfully" +msgstr "Service erfolgreich deinstalliert" + +#. Programmer's name for it: SServiceUninstallFailed +#: Vcl/consts.pas:297 +msgid "Service \"%s\" failed to uninstall with error: \"%s\"" +msgstr "Service \"%s\" konnte nicht deinstalliert werden; Fehler: \"%s\"" + +#. Programmer's name for it: SInvalidActionRegistration +#: Vcl/consts.pas:299 +msgid "Invalid action registration" +msgstr "Ungültige Aktionsregistrierung" + +#. Programmer's name for it: SInvalidActionUnregistration +#: Vcl/consts.pas:300 +msgid "Invalid action unregistration" +msgstr "Ungültige Aufhebung der Aktionsregistrierung" + +#. Programmer's name for it: SInvalidActionEnumeration +#: Vcl/consts.pas:301 +msgid "Invalid action enumeration" +msgstr "Ungültige Aktionsaufzählung" + +#. Programmer's name for it: SInvalidActionCreation +#: Vcl/consts.pas:302 +msgid "Invalid action creation" +msgstr "Ungültige Aktionserstellung" + +#. Programmer's name for it: SDockedCtlNeedsName +#: Vcl/consts.pas:304 +msgid "Docked control must have a name" +msgstr "Angedocktes Steuerelement muß einen Namen haben." + +#. Programmer's name for it: SDockTreeRemoveError +#: Vcl/consts.pas:305 +msgid "Error removing control from dock tree" +msgstr "Fehler beim Entfernen des Steuerelements aus der Andock-Hierarchie" + +#. Programmer's name for it: SDockZoneNotFound +#: Vcl/consts.pas:306 +msgid " - Dock zone not found" +msgstr " - Andockzone nicht gefunden" + +#. Programmer's name for it: SDockZoneHasNoCtl +#: Vcl/consts.pas:307 +msgid " - Dock zone has no control" +msgstr " - Andockzone besitzt kein Steuerelement" + +#. Programmer's name for it: SAllCommands +#: Vcl/consts.pas:309 +msgid "All Commands" +msgstr "Alle Befehle" + +#. Programmer's name for it: SDuplicateItem +#: Vcl/consts.pas:311 +msgid "List does not allow duplicates ($0%x)" +msgstr "Liste gestattet keine doppelten Einträge ($0%x)" + +#. Programmer's name for it: SDuplicatePropertyCategory +#: Vcl/consts.pas:313 +msgid "A property category called %s already exists" +msgstr "Eine Eigenschaftskategorie mit Namen %s gibt es bereits" + +#. Programmer's name for it: SUnknownPropertyCategory +#: Vcl/consts.pas:314 +msgid "Property category does not exist (%s)" +msgstr "Eigenschaftskategorie existiert nicht (%s)" + +#. Programmer's name for it: SActionCategoryName +#: Vcl/consts.pas:316 +msgid "Action" +msgstr "Aktion" + +#. Programmer's name for it: SActionCategoryDesc +#: Vcl/consts.pas:317 +msgid "Action properties and/or events" +msgstr "Aktionen Eigenschaften/Ereignisse" + +#. Programmer's name for it: SDataCategoryName +#: Vcl/consts.pas:318 +msgid "Data" +msgstr "Daten" + +#. Programmer's name for it: SDataCategoryDesc +#: Vcl/consts.pas:319 +msgid "Data properties and/or events" +msgstr "Dateneigenschaften und/oder -ereignisse" + +#. Programmer's name for it: SDatabaseCategoryName +#: Vcl/consts.pas:320 +msgid "Database" +msgstr "Datenbank" + +#. Programmer's name for it: SDatabaseCategoryDesc +#: Vcl/consts.pas:321 +msgid "Database and Data Aware properties and/or events" +msgstr "Daten- und datenbankbezogene Eigenschaften/Ereignisse" + +#. Programmer's name for it: SDragNDropCategoryName +#: Vcl/consts.pas:322 +msgid "Drag, Drop and Docking" +msgstr "Drag, Drop und Docking" + +#. Programmer's name for it: SDragNDropCategoryDesc +#: Vcl/consts.pas:323 +msgid "Drag, Drop and Docking properties and/or events" +msgstr "Eigenschaften/Ereignisse zu Drag, Drop und Docking" + +#. Programmer's name for it: SHelpCategoryName +#: Vcl/consts.pas:324 +msgid "Help and Hints" +msgstr "Hilfe und Hinweise" + +#. Programmer's name for it: SHelpCategoryDesc +#: Vcl/consts.pas:325 +msgid "Help and Hint properties and/or events" +msgstr "Eigenschaften/Ereignisse zu: Hilfe und Hinweise" + +#. Programmer's name for it: SLayoutCategoryName +#: Vcl/consts.pas:326 +msgid "Layout" +msgstr "Layout" + +#. Programmer's name for it: SLayoutCategoryDesc +#: Vcl/consts.pas:327 +msgid "Layout properties and/or events" +msgstr "Layout Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLegacyCategoryName +#: Vcl/consts.pas:328 +msgid "Legacy" +msgstr "Legacy" + +#. Programmer's name for it: SLegacyCategoryDesc +#: Vcl/consts.pas:329 +msgid "Legacy properties and/or events" +msgstr "Vererbungsrelevante Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLinkageCategoryName +#: Vcl/consts.pas:330 +msgid "Linkage" +msgstr "Linkage" + +#. Programmer's name for it: SLinkageCategoryDesc +#: Vcl/consts.pas:331 +msgid "Linkage properties and/or events" +msgstr "Verbindungsbezogene Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLocaleCategoryName +#: Vcl/consts.pas:332 +msgid "Locale" +msgstr "Länderkennung" + +#. Programmer's name for it: SLocaleCategoryDesc +#: Vcl/consts.pas:333 +msgid "Locale properties and/or events" +msgstr "Lokale Eigenschaften/Ereignisse" + +#. Programmer's name for it: SLocalizableCategoryName +#: Vcl/consts.pas:334 +msgid "Localizable" +msgstr "Übersetzungsrelevant" + +#. Programmer's name for it: SLocalizableCategoryDesc +#: Vcl/consts.pas:335 +msgid "Localizable properties and/or events" +msgstr "Lokalisierbare Eigenschaften/Ereignisse" + +#. Programmer's name for it: SMiscellaneousCategoryName +#: Vcl/consts.pas:336 +msgid "Miscellaneous" +msgstr "Verschiedene" + +#. Programmer's name for it: SMiscellaneousCategoryDesc +#: Vcl/consts.pas:337 +msgid "Miscellaneous properties and/or events" +msgstr "Sonstige Eigenschaften/Ereignisse" + +#. Programmer's name for it: SVisualCategoryName +#: Vcl/consts.pas:338 +msgid "Visual" +msgstr "Visuell" + +#. Programmer's name for it: SVisualCategoryDesc +#: Vcl/consts.pas:339 +msgid "Visual properties and/or events" +msgstr "Visuelle Eigenschaften/Ereignisse" + +#. Programmer's name for it: SInputCategoryName +#: Vcl/consts.pas:340 +msgid "Input" +msgstr "Eingabe" + +#. Programmer's name for it: SInputCategoryDesc +#: Vcl/consts.pas:341 +msgid "Input properties and/or events" +msgstr "Eingabebezogene Eigenschaften/Ereignisse" + +#. Programmer's name for it: SInvalidMask +#: Vcl/consts.pas:343 +msgid "'%s' is an invalid mask at (%d)" +msgstr "'%s' ist eine ungültige Maske für (%d)" + +#. Programmer's name for it: SInvalidFilter +#: Vcl/consts.pas:344 +msgid "Property filters may only be name, class or type based (%d:%d)" +msgstr "Eigenschaftsfilter dürfen nur auf Name, Klasse oder Typ basieren (%d:%d)" + +#. Programmer's name for it: SInvalidCategory +#: Vcl/consts.pas:345 +msgid "Categories must define their own name and description" +msgstr "Kategorien müssen ihre eigenen Namen und Beschreibung definieren" + +#. Programmer's name for it: sOperationNotAllowed +#: Vcl/consts.pas:347 +msgid "Operation not allowed while dispatching application events" +msgstr "Operation bei der Weiterleitung von Anwendungsereignissen nicht gestattet" + +#. Programmer's name for it: sInvalidClassReference +#: Vcl/ctlpanel.pas:129 +msgid "Invalid class reference for TAppletApplication" +msgstr "Ungültige Klassenreferenz für TAppletApplication" + +#. Programmer's name for it: SInvalidFieldSize +#: Vcl/dbconsts.pas:15 +msgid "Invalid field size" +msgstr "Ungültige Feldgröße" + +#. Programmer's name for it: SInvalidFieldKind +#: Vcl/dbconsts.pas:16 +msgid "Invalid FieldKind" +msgstr "FieldKind ungültig" + +#. Programmer's name for it: SInvalidFieldRegistration +#: Vcl/dbconsts.pas:17 +msgid "Invalid field registration" +msgstr "Ungültige Feldregistrierung" + +#. Programmer's name for it: SUnknownFieldType +#: Vcl/dbconsts.pas:18 +msgid "Field '%s' is of an unknown type" +msgstr "Typ für Feld '%s' ist unbekannt" + +#. Programmer's name for it: SFieldNameMissing +#: Vcl/dbconsts.pas:19 +msgid "Field name missing" +msgstr "Feldname fehlt" + +#. Programmer's name for it: SDuplicateFieldName +#: Vcl/dbconsts.pas:20 +msgid "Duplicate field name '%s'" +msgstr "Doppelter Feldname '%s'" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/dbconsts.pas:21 +msgid "Field '%s' not found" +msgstr "Das Feld '%s' wurde nicht gefunden" + +#. Programmer's name for it: SFieldAccessError +#: Vcl/dbconsts.pas:22 +msgid "Cannot access field '%s' as type %s" +msgstr "Feld '%s' kann nicht als Typ %s angesprochen werden" + +#. Programmer's name for it: SFieldValueError +#: Vcl/dbconsts.pas:23 +msgid "Invalid value for field '%s'" +msgstr "Ungültiger Wert für Feld '%s'" + +#. Programmer's name for it: SFieldRangeError +#: Vcl/dbconsts.pas:24 +msgid "%g is not a valid value for field '%s'. The allowed range is %g to %g" +msgstr "%g ist kein gültiger Wert für das Feld '%s'. Der zulässige Bereich ist %g bis %g" + +#. Programmer's name for it: SInvalidIntegerValue +#: Vcl/dbconsts.pas:25 +msgid "'%s' is not a valid integer value for field '%s'" +msgstr "'%s' ist kein gültiger Integerwert für Feld '%s'" + +#. Programmer's name for it: SInvalidBoolValue +#: Vcl/dbconsts.pas:26 +msgid "'%s' is not a valid boolean value for field '%s'" +msgstr "'%s' ist kein gültiger boolescher Wert für Feld '%s'" + +#. Programmer's name for it: SInvalidFloatValue +#: Vcl/dbconsts.pas:27 +msgid "'%s' is not a valid floating point value for field '%s'" +msgstr "'%s' ist kein gültiger Fließkommawert für Feld '%s'" + +#. Programmer's name for it: SFieldTypeMismatch +#: Vcl/dbconsts.pas:28 +msgid "Type mismatch for field '%s', expecting: %s actual: %s" +msgstr "Unterschiedliche Typen für Feld '%s'; erwartet: %s, gefunden: %s" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/dbconsts.pas:29 +msgid "Size mismatch for field '%s', expecting: %d actual: %d" +msgstr "Unterschiedliche Größe für Feld '%s'; erwartet: %d, gefunden: %d" + +#. Programmer's name for it: SInvalidVarByteArray +#: Vcl/dbconsts.pas:30 +msgid "Invalid variant type or size for field '%s'" +msgstr "Variant-Typ oder -größe für Feld '%s' ist ungültig" + +#. Programmer's name for it: SFieldOutOfRange +#: Vcl/dbconsts.pas:31 +msgid "Value of field '%s' is out of range" +msgstr "Wert des Feldes '%s' ist außerhalb des zulässigen Bereichs" + +#. Programmer's name for it: SBCDOverflow +#: Vcl/dbconsts.pas:32 +msgid "(Overflow)" +msgstr "(Überlauf)" + +#. Programmer's name for it: SFieldRequired +#: Vcl/dbconsts.pas:33 +msgid "Field '%s' must have a value" +msgstr "Feld '%s' muss einen Wert haben" + +#. Programmer's name for it: SDataSetMissing +#: Vcl/dbconsts.pas:34 +msgid "Field '%s' has no dataset" +msgstr "Feld '%s' hat keine Datenmenge" + +#. Programmer's name for it: SInvalidCalcType +#: Vcl/dbconsts.pas:35 +msgid "Field '%s' cannot be a calculated or lookup field" +msgstr "Feld '%s' kann kein berechnetes oder Nachschlage-Feld sein" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/dbconsts.pas:36 +msgid "Field '%s' cannot be modified" +msgstr "Feld '%s' kann nicht verändert werden" + +#. Programmer's name for it: SFieldIndexError +#: Vcl/dbconsts.pas:37 +msgid "Field index out of range" +msgstr "Feldindex außerhalb des gültigen Bereichs" + +#. Programmer's name for it: SNoFieldIndexes +#: Vcl/dbconsts.pas:38 +msgid "No index currently active" +msgstr "Es ist momentan kein Index aktiv" + +#. Programmer's name for it: SNotIndexField +#: Vcl/dbconsts.pas:39 +msgid "Field '%s' is not indexed and cannot be modified" +msgstr "Feld '%s' ist nicht indiziert und kann nicht verändert werden" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/dbconsts.pas:40 +msgid "Cannot access index field '%s'" +msgstr "Zugriff auf Indexfeld '%s' nicht möglich" + +#. Programmer's name for it: SDuplicateIndexName +#: Vcl/dbconsts.pas:41 +msgid "Duplicate index name '%s'" +msgstr "Doppelter Indexname '%s'" + +#. Programmer's name for it: SNoIndexForFields +#: Vcl/dbconsts.pas:42 +msgid "No index for fields '%s'" +msgstr "Kein Index für die Felder '%s' vorhanden" + +#. Programmer's name for it: SIndexNotFound +#: Vcl/dbconsts.pas:43 +msgid "Index '%s' not found" +msgstr "Index '%s' wurde nicht gefunden" + +#. Programmer's name for it: SDuplicateName +#: Vcl/dbconsts.pas:44 +msgid "Duplicate name '%s' in %s" +msgstr "Doppelter Name '%s' in %s" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/dbconsts.pas:45 +msgid "Circular datalinks are not allowed" +msgstr "Zirkuläre Datenverbindungen sind nicht erlaubt" + +#. Programmer's name for it: SLookupInfoError +#: Vcl/dbconsts.pas:46 +msgid "Lookup information for field '%s' is incomplete" +msgstr "Lookup-Information für Feld '%s' ist unvollständig" + +#. Programmer's name for it: SDataSourceChange +#: Vcl/dbconsts.pas:47 +msgid "DataSource cannot be changed" +msgstr "DataSource kann nicht geändert werden" + +#. Programmer's name for it: SNoNestedMasterSource +#: Vcl/dbconsts.pas:48 +msgid "Nested datasets cannot have a MasterSource" +msgstr "Bei verschachtelten Datenmengen ist MasterSource nicht zulässig" + +#. Programmer's name for it: SDataSetOpen +#: Vcl/dbconsts.pas:49 +msgid "Cannot perform this operation on an open dataset" +msgstr "Operation bei geöffneter Datenmenge nicht ausführbar" + +#. Programmer's name for it: SNotEditing +#: Vcl/dbconsts.pas:50 +msgid "Dataset not in edit or insert mode" +msgstr "Datenmenge weder im Editier- noch im Einfügemodus" + +#. Programmer's name for it: SDataSetClosed +#: Vcl/dbconsts.pas:51 +msgid "Cannot perform this operation on a closed dataset" +msgstr "Operation bei geschlossener Datenmenge nicht ausführbar" + +#. Programmer's name for it: SDataSetEmpty +#: Vcl/dbconsts.pas:52 +msgid "Cannot perform this operation on an empty dataset" +msgstr "Operation bei leerer Datenmenge nicht ausführbar" + +#. Programmer's name for it: SDataSetReadOnly +#: Vcl/dbconsts.pas:53 +msgid "Cannot modify a read-only dataset" +msgstr "Eine Datenmenge, die nur zum Lesen ist, kann nicht geändert werden" + +#. Programmer's name for it: SNestedDataSetClass +#: Vcl/dbconsts.pas:54 +msgid "Nested dataset must inherit from %s" +msgstr "Verschachtelte Datenmengen müssen von %s vererbt sein" + +#. Programmer's name for it: SExprTermination +#: Vcl/dbconsts.pas:55 +msgid "Filter expression incorrectly terminated" +msgstr "Filterausdruck fehlerhaft abgeschlossen" + +#. Programmer's name for it: SExprNameError +#: Vcl/dbconsts.pas:56 +msgid "Unterminated field name" +msgstr "Nicht begrenzter Feldname" + +#. Programmer's name for it: SExprStringError +#: Vcl/dbconsts.pas:57 +msgid "Unterminated string constant" +msgstr "Nicht begrenzte String-Konstante" + +#. Programmer's name for it: SExprInvalidChar +#: Vcl/dbconsts.pas:58 +msgid "Invalid filter expression character: '%s'" +msgstr "Ungültiges Zeichen in Filterausdruck: '%s'" + +#. Programmer's name for it: SExprNoLParen +#: Vcl/dbconsts.pas:59 +msgid "'(' expected but %s found" +msgstr "'(' erwartet, aber %s vorgefunden" + +#. Programmer's name for it: SExprNoRParen +#: Vcl/dbconsts.pas:60 +msgid "')' expected but %s found" +msgstr "')' erwartet, jedoch %s vorgefunden" + +#. Programmer's name for it: SExprNoRParenOrComma +#: Vcl/dbconsts.pas:61 +msgid "')' or ',' expected but %s found" +msgstr "')' oder ',' erwartet, jedoch %s vorgefunden" + +#. Programmer's name for it: SExprExpected +#: Vcl/dbconsts.pas:62 +msgid "Expression expected but %s found" +msgstr "Ausdruck erwartet, jedoch %s vorgefunden" + +#. Programmer's name for it: SExprBadField +#: Vcl/dbconsts.pas:63 +msgid "Field '%s' cannot be used in a filter expression" +msgstr "Feld '%s' kann nicht in einem Filterausdruck verwendet werden" + +#. Programmer's name for it: SExprBadNullTest +#: Vcl/dbconsts.pas:64 +msgid "NULL only allowed with '=' and '<>'" +msgstr "NULL ist nur mit '=' und '<>' erlaubt" + +#. Programmer's name for it: SExprRangeError +#: Vcl/dbconsts.pas:65 +msgid "Constant out of range" +msgstr "Konstante außerhalb des zulässigen Wertebereichs" + +#. Programmer's name for it: SExprNotBoolean +#: Vcl/dbconsts.pas:66 +msgid "Field '%s' is not of type Boolean" +msgstr "Feld '%s' ist kein boolescher Typ" + +#. Programmer's name for it: SExprIncorrect +#: Vcl/dbconsts.pas:67 +msgid "Incorrectly formed filter expression" +msgstr "Ungültiger Filterausdruck" + +#. Programmer's name for it: SExprNothing +#: Vcl/dbconsts.pas:68 +msgid "nothing" +msgstr "leer" + +#. Programmer's name for it: SExprTypeMis +#: Vcl/dbconsts.pas:69 +msgid "Type mismatch in expression" +msgstr "Fehlende Typübereinstimmung im Ausdruck" + +#. Programmer's name for it: SExprBadScope +#: Vcl/dbconsts.pas:70 +msgid "Operation cannot mix aggregate value with record-varying value" +msgstr "Die Operation kann keine Zusammenfassungswerte mit Datensatzwerten mischen" + +#. Programmer's name for it: SExprNoArith +#: Vcl/dbconsts.pas:71 +msgid "Arithmetic in filter expressions not supported" +msgstr "Arithmetische Filterausdrücke werden nicht unterstützt" + +#. Programmer's name for it: SExprNotAgg +#: Vcl/dbconsts.pas:72 +msgid "Expression is not an aggregate expression" +msgstr "Der Ausdruck ist kein Aggregat-Ausdruck" + +#. Programmer's name for it: SExprBadConst +#: Vcl/dbconsts.pas:73 +msgid "Constant is not correct type %s" +msgstr "Die Konstante ist nicht vom richtigen Typ %s" + +#. Programmer's name for it: SExprNoAggFilter +#: Vcl/dbconsts.pas:74 +msgid "Aggregate expressions not allowed in filters" +msgstr "In Filtern sind keine Aggregationsausdrücke erlaubt" + +#. Programmer's name for it: SExprEmptyInList +#: Vcl/dbconsts.pas:75 +msgid "IN predicate list may not be empty" +msgstr "Die IN-Liste darf nicht leer bleiben" + +#. Programmer's name for it: SInvalidKeywordUse +#: Vcl/dbconsts.pas:76 +msgid "Invalid use of keyword" +msgstr "Ungültige Verwendung eines Schlüsselworts" + +#. Programmer's name for it: SParameterNotFound +#: Vcl/dbconsts.pas:79 +msgid "Parameter '%s' not found" +msgstr "Parameter '%s' nicht gefunden" + +#. Programmer's name for it: SInvalidVersion +#: Vcl/dbconsts.pas:80 +msgid "Unable to load bind parameters" +msgstr "Bind-Parameter können nicht geladen werden" + +#. Programmer's name for it: SParamTooBig +#: Vcl/dbconsts.pas:81 +msgid "Parameter '%s', cannot save data larger than %d bytes" +msgstr "Parameter '%s': Daten, die größer sind als %d Byte, können nicht gespeichert werden" + +#. Programmer's name for it: SBadFieldType +#: Vcl/dbconsts.pas:82 +msgid "Field '%s' is of an unsupported type" +msgstr "Der Typ von Feld '%s' wird nicht unterstützt" + +#. Programmer's name for it: SAggActive +#: Vcl/dbconsts.pas:83 +msgid "Property may not be modified while aggregate is active" +msgstr "Die Eigenschaft kann nicht geändert werden, während die Aggregatfunktion aktiv ist" + +#. Programmer's name for it: SProviderSQLNotSupported +#: Vcl/dbconsts.pas:84 +msgid "SQL not supported: %s" +msgstr "SQL nicht unterstützt: %s" + +#. Programmer's name for it: SProviderExecuteNotSupported +#: Vcl/dbconsts.pas:85 +msgid "Execute not supported: %s" +msgstr "Ausführung nicht unterstützt: %s" + +#. Programmer's name for it: SExprNoAggOnCalcs +#: Vcl/dbconsts.pas:86 +msgid "Field '%s' is not the correct type of calculated field to be used in an aggregate, use an internalcalc" +msgstr "Feld '%s' ist nicht der korrekte Typ eines berechneten Feldes für eine Aggregierung; verwenden Sie internalcalc" + +#. Programmer's name for it: SRecordChanged +#: Vcl/dbconsts.pas:87 +msgid "Record changed by another user" +msgstr "Der Datensatz wurde von einem anderen Anwender geändert" + +#. Programmer's name for it: SFirstRecord +#: Vcl/dbconsts.pas:90 +msgid "First record" +msgstr "Erster Datensatz" + +#. Programmer's name for it: SPriorRecord +#: Vcl/dbconsts.pas:91 +msgid "Prior record" +msgstr "Vorheriger Datensatz" + +#. Programmer's name for it: SNextRecord +#: Vcl/dbconsts.pas:92 +msgid "Next record" +msgstr "Nächster Datensatz" + +#. Programmer's name for it: SLastRecord +#: Vcl/dbconsts.pas:93 +msgid "Last record" +msgstr "Letzter Datensatz" + +#. Programmer's name for it: SInsertRecord +#: Vcl/dbconsts.pas:94 +msgid "Insert record" +msgstr "Datensatz einfügen" + +#. Programmer's name for it: SDeleteRecord +#: Vcl/dbconsts.pas:95 +msgid "Delete record" +msgstr "Datensatz löschen" + +#. Programmer's name for it: SEditRecord +#: Vcl/dbconsts.pas:96 +msgid "Edit record" +msgstr "Datensatz bearbeiten" + +#. Programmer's name for it: SPostEdit +#: Vcl/dbconsts.pas:97 +msgid "Post edit" +msgstr "Übernehmen" + +#. Programmer's name for it: SCancelEdit +#: Vcl/dbconsts.pas:98 +msgid "Cancel edit" +msgstr "Bearbeiten abbrechen" + +#. Programmer's name for it: SRefreshRecord +#: Vcl/dbconsts.pas:99 +msgid "Refresh data" +msgstr "Daten aktualisieren" + +#. Programmer's name for it: SDeleteRecordQuestion +#: Vcl/dbconsts.pas:100 +msgid "Delete record?" +msgstr "Datensatz löschen?" + +#. Programmer's name for it: SDeleteMultipleRecordsQuestion +#: Vcl/dbconsts.pas:101 +msgid "Delete all selected records?" +msgstr "Alle markierten Datensätze löschen?" + +#. Programmer's name for it: SRecordNotFound +#: Vcl/dbconsts.pas:102 +msgid "Record not found" +msgstr "Datensatz nicht gefunden" + +#. Programmer's name for it: SDataSourceFixed +#: Vcl/dbconsts.pas:103 +msgid "Operation not allowed in a DBCtrlGrid" +msgstr "Operation in einem DBCtrlGrid nicht erlaubt" + +#. Programmer's name for it: SNotReplicatable +#: Vcl/dbconsts.pas:104 +msgid "Control cannot be used in a DBCtrlGrid" +msgstr "Element kann in einem DBCtrlGrid nicht verwendet werden" + +#. Programmer's name for it: SPropDefByLookup +#: Vcl/dbconsts.pas:105 +msgid "Property already defined by lookup field" +msgstr "Eigenschaft bereits durch Lookup-Feld definiert" + +#. Programmer's name for it: STooManyColumns +#: Vcl/dbconsts.pas:106 +msgid "Grid requested to display more than 256 columns" +msgstr "Gitter soll mehr als 256 Spalten darstellen" + +#. Programmer's name for it: SRemoteLogin +#: Vcl/dbconsts.pas:109 +msgid "Remote Login" +msgstr "Externe Anmeldung" + +#. Programmer's name for it: SDataBindings +#: Vcl/dbconsts.pas:112 +msgid "Data Bindings..." +msgstr "Datenbindungen..." + +#. Programmer's name for it: SIBTransactionEditor +#: Vcl/ib.pas:156 +msgid "&Transaction Editor..." +msgstr "Transa&ktions-Editor..." + +#. Programmer's name for it: SDatabaseFilter +#: Vcl/ib.pas:157 +msgid "Database Files (*.gdb)|*.gdb|All files (*.*)|*.*" +msgstr "Datenbank-Dateien (*.gdb)|*.gdb|Alle Dateien (*.*)|*.*" + +#. Programmer's name for it: SCommitTransaction +#: Vcl/ib.pas:159 +msgid "Transaction is currently Active. Rollback and continue?" +msgstr "Es ist gerade eine Transaktion aktiv. Zurücksetzen und weitermachen?" + +#. Programmer's name for it: SUnknownError +#: Vcl/ib.pas:168 +msgid "Unknown error" +msgstr "Unbekannter Fehler." + +#. Programmer's name for it: SInterBaseMissing +#: Vcl/ib.pas:169 +msgid "InterBase library gds32.dll not found in the path. Please install InterBase to use this functionality" +msgstr "InterBase-DLL gds32.dll wurde im Pfad nicht gefunden" + +#. Programmer's name for it: SInterBaseInstallMissing +#: Vcl/ib.pas:170 +msgid "InterBase Install DLL ibinstall.dll not found in the path. Please install InterBase 6 to use this functionality" +msgstr "Die InterBase-Installations-DLL ibinstall.dll wurde im Pfad nicht gefunden" + +#. Programmer's name for it: SIB60feature +#: Vcl/ib.pas:171 +msgid "%s is an InterBase6 function. Please upgrade to InterBase6 to use this functonality" +msgstr "%s ist eine Funktion von InterBase 6. Um diese Funktionalität zu nutzen, müssen Sie auf IB6 updaten" + +#. Programmer's name for it: SNotSupported +#: Vcl/ib.pas:172 +msgid "Unsupported feature" +msgstr "Nicht unterstütztes Merkmal." + +#. Programmer's name for it: SNotPermitted +#: Vcl/ib.pas:173 +msgid "Not permitted" +msgstr "Nicht gestattet." + +#. Programmer's name for it: SFileAccessError +#: Vcl/ib.pas:174 +msgid "Temporary file access error" +msgstr "Zugriffsfehler bei temporären Dateien." + +#. Programmer's name for it: SConnectionTimeout +#: Vcl/ib.pas:175 +msgid "Database connection timed out" +msgstr "Zeitüberschreitung bei Datenbankverbindung." + +#. Programmer's name for it: SCannotSetDatabase +#: Vcl/ib.pas:176 +msgid "Cannot set database" +msgstr "Datenbank kann nicht gesetzt werden." + +#. Programmer's name for it: SCannotSetTransaction +#: Vcl/ib.pas:177 +msgid "Cannot set transaction" +msgstr "Transaktion kann nicht gesetzt werden." + +#. Programmer's name for it: SOperationCancelled +#: Vcl/ib.pas:178 +msgid "Operation cancelled at user's request" +msgstr "Die Operation wurde auf Anforderung des Anwenders abgebrochen." + +#. Programmer's name for it: SDPBConstantNotSupported +#: Vcl/ib.pas:179 +msgid "DPB Constant (isc_dpb_%s) is unsupported" +msgstr "DPB-Konstante (isc_dpb_%s) wird nicht unterstützt." + +#. Programmer's name for it: SDPBConstantUnknown +#: Vcl/ib.pas:180 +msgid "DPB Constant (%d) is unknown" +msgstr "DPB-Konstante (%d) ist unbekannt." + +#. Programmer's name for it: STPBConstantNotSupported +#: Vcl/ib.pas:181 +msgid "TPB Constant (isc_tpb_%s) is unsupported" +msgstr "TPB-Konstante (isc_tpb_%s) ist nicht unterstützt." + +#. Programmer's name for it: STPBConstantUnknown +#: Vcl/ib.pas:182 +msgid "TPB Constant (%d) is unknown" +msgstr "TPB-Konstante (%d) ist unbekannt." + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/ib.pas:183 +msgid "Cannot perform operation -- DB is not open" +msgstr "Operation kann nicht durchgeführt werden -- DB ist nicht offen." + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/ib.pas:184 +msgid "Cannot perform operation -- DB is currently open" +msgstr "Operation kann nicht durchgeführt werden -- DB ist im Moment geöffnet." + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/ib.pas:185 +msgid "Database name is missing" +msgstr "Der Name der Datenbank fehlt." + +#. Programmer's name for it: SNotInTransaction +#: Vcl/ib.pas:186 +msgid "Transaction is not active" +msgstr "Transaktion ist nicht aktiv." + +#. Programmer's name for it: SInTransaction +#: Vcl/ib.pas:187 +msgid "Transaction is active" +msgstr "Transaktion ist aktiv." + +#. Programmer's name for it: STimeoutNegative +#: Vcl/ib.pas:188 +msgid "Timeout values cannot be negative" +msgstr "Werte für Zeitüberschreitung dürfen nicht negativ sein." + +#. Programmer's name for it: SNoDatabasesInTransaction +#: Vcl/ib.pas:189 +msgid "No databases are listed in transaction component" +msgstr "In der Transaktionskomponente sind keine Datenbanken aufgeführt." + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/ib.pas:190 +msgid "Updating wrong database" +msgstr "Es wurde die falsche Datenbank aktualisiert." + +#. Programmer's name for it: SUpdateWrongTR +#: Vcl/ib.pas:191 +msgid "Updating wrong transaction. Unique transaction expected in set" +msgstr "Aktualisierung der falschen Transaktion. In der Menge wird eine eindeutige Transaktion erwartet" + +#. Programmer's name for it: SDatabaseNotAssigned +#: Vcl/ib.pas:192 +msgid "Database not assigned" +msgstr "Datenbank nicht zugewiesen." + +#. Programmer's name for it: STransactionNotAssigned +#: Vcl/ib.pas:193 +msgid "Transaction not assigned" +msgstr "Transaktion ist nicht zugewiesen." + +#. Programmer's name for it: SXSQLDAIndexOutOfRange +#: Vcl/ib.pas:194 +msgid "XSQLDA index out of range" +msgstr "XSQLDA-Index außerhalb des gültigen Bereichs." + +#. Programmer's name for it: SXSQLDANameDoesNotExist +#: Vcl/ib.pas:195 +msgid "XSQLDA name does not exist (%s)" +msgstr "XSQLDA-Name existiert nicht (%s)." + +#. Programmer's name for it: SEOF +#: Vcl/ib.pas:196 +msgid "End of file" +msgstr "Ende der Datei." + +#. Programmer's name for it: SBOF +#: Vcl/ib.pas:197 +msgid "Beginning of file" +msgstr "Beginn der Datei." + +#. Programmer's name for it: SInvalidStatementHandle +#: Vcl/ib.pas:198 +msgid "Invalid statement handle" +msgstr "Ungültiges Anweisungs-Handle." + +#. Programmer's name for it: SSQLOpen +#: Vcl/ib.pas:199 +msgid "IBSQL Open" +msgstr "IBSQL geöffnet" + +#. Programmer's name for it: SSQLClosed +#: Vcl/ib.pas:200 +msgid "IBSQL Closed" +msgstr "IBSQL geschlossen" + +#. Programmer's name for it: SDatasetOpen +#: Vcl/ib.pas:201 +msgid "Dataset open" +msgstr "Datenmenge geöffnet." + +#. Programmer's name for it: SDatasetClosed +#: Vcl/ib.pas:202 +msgid "Dataset closed" +msgstr "Datenmenge geschlossen." + +#. Programmer's name for it: SUnknownSQLDataType +#: Vcl/ib.pas:203 +msgid "Unknown SQL Data type (%d)" +msgstr "Unbekannter SQL-Datentyp (%d)." + +#. Programmer's name for it: SInvalidColumnIndex +#: Vcl/ib.pas:204 +msgid "Invalid column index (index exceeds permitted range)" +msgstr "Ungültiger Spaltenindex (Der Index überschreitet den erlaubten Bereich)." + +#. Programmer's name for it: SInvalidParamColumnIndex +#: Vcl/ib.pas:205 +msgid "Invalid parameter index (index exceeds permitted range)" +msgstr "Ungültiger Parameterindex (Der Index überschreitet den erlaubten Bereich)." + +#. Programmer's name for it: SInvalidDataConversion +#: Vcl/ib.pas:206 +msgid "Invalid data conversion" +msgstr "Ungültige Datenkonvertierung." + +#. Programmer's name for it: SColumnIsNotNullable +#: Vcl/ib.pas:207 +msgid "Column cannot be set to null (%s)" +msgstr "Spalte kann nicht auf null gesetzt werden (%s)" + +#. Programmer's name for it: SBlobCannotBeRead +#: Vcl/ib.pas:208 +msgid "Blob stream cannot be read" +msgstr "Blob-Stream kann nicht gelesen werden." + +#. Programmer's name for it: SBlobCannotBeWritten +#: Vcl/ib.pas:209 +msgid "Blob stream cannot be written" +msgstr "Blob-Stream kann nicht geschrieben werden." + +#. Programmer's name for it: SEmptyQuery +#: Vcl/ib.pas:210 +msgid "Empty query" +msgstr "Leere Abfrage." + +#. Programmer's name for it: SCannotOpenNonSQLSelect +#: Vcl/ib.pas:211 +msgid "Cannot \"open\" a non-select statement. Use ExecQuery" +msgstr "Ein Nicht-Select-Statement kann nicht \"geöffnet\" werden. Verwenden Sie ExecQuery." + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/ib.pas:212 +msgid "No access to field \"%s\"" +msgstr "Kein Zugriff auf Feld \"%s\"." + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/ib.pas:213 +msgid "Field \"%s\" is read-only" +msgstr "Feld \"%s\" ist schreibgeschützt." + +#. Programmer's name for it: SFieldNotFound +#: Vcl/ib.pas:214 +msgid "Field \"%s\" not found" +msgstr "Feld \"%s\" konnte nicht gefunden werden." + +#. Programmer's name for it: SNotEditing +#: Vcl/ib.pas:215 +msgid "Not editing" +msgstr "Kein Bearbeiten." + +#. Programmer's name for it: SCannotInsert +#: Vcl/ib.pas:216 +msgid "Cannot insert into dataset. (No insert query)" +msgstr "In Datenmenge kann nicht eingefügt werden. (Keine Einfüge-Abfrage)." + +#. Programmer's name for it: SCannotPost +#: Vcl/ib.pas:217 +msgid "Cannot post. (No update/insert query)" +msgstr "Zurückschreiben nicht möglich. (Keine Aktualisierungs-/Einfügen-Abfrage)" + +#. Programmer's name for it: SCannotUpdate +#: Vcl/ib.pas:218 +msgid "Cannot update. (No update query)" +msgstr "Keine Aktualisierung möglich. (Keine Aktualisierungs-Abfrage)." + +#. Programmer's name for it: SCannotDelete +#: Vcl/ib.pas:219 +msgid "Cannot delete from dataset. (No delete query)" +msgstr "Aus der Datenmenge kann nichts gelöscht werden. (Keine Lösch-Abfrage)." + +#. Programmer's name for it: SCannotRefresh +#: Vcl/ib.pas:220 +msgid "Cannot refresh row. (No refresh query)" +msgstr "Zeile kann nicht aktualisiert werden. (Keine Aktualisierungs-Abfrage)." + +#. Programmer's name for it: SBufferNotSet +#: Vcl/ib.pas:221 +msgid "Buffer not set" +msgstr "Puffer nicht gesetzt." + +#. Programmer's name for it: SCircularReference +#: Vcl/ib.pas:222 +msgid "Circular references not permitted" +msgstr "Zirkuläre Verweise sind nicht gestattet." + +#. Programmer's name for it: SSQLParseError +#: Vcl/ib.pas:223 +msgid "" +"SQL Parse Error:\n" +"\n" +"%s" +msgstr "" +"Fehler bei der SQL-Auswertung:\n" +"\n" +"%s" + +#. Programmer's name for it: SUserAbort +#: Vcl/ib.pas:224 +msgid "User abort" +msgstr "Abbruch durch Anwender." + +#. Programmer's name for it: SDataSetUniDirectional +#: Vcl/ib.pas:225 +msgid "Data set is uni-directional" +msgstr "Datenmenge ist unidirektional." + +#. Programmer's name for it: SCannotCreateSharedResource +#: Vcl/ib.pas:226 +msgid "Cannot create shared resource. (Windows error %d)" +msgstr "Gemeinsam genutzte Ressource kann nicht erzeugt werden. (Windows-Fehler %d)" + +#. Programmer's name for it: SWindowsAPIError +#: Vcl/ib.pas:227 +msgid "Windows API error. (Windows error %d [$%.8x])" +msgstr "Fehler der Windows-API. (Windows-Fehler %d [$%.8x])" + +#. Programmer's name for it: SColumnListsDontMatch +#: Vcl/ib.pas:228 +msgid "Column lists do not match" +msgstr "Fehlende Überinstimmung bei Spaltenlisten." + +#. Programmer's name for it: SColumnTypesDontMatch +#: Vcl/ib.pas:229 +msgid "Column types don't match. (From index: %d; To index: %d)" +msgstr "Spaltentypen stimmen nicht überein. (Von Index: %d; Zu Index: %d)" + +#. Programmer's name for it: SCantEndSharedTransaction +#: Vcl/ib.pas:231 +msgid "Can't end a shared transaction unless it is forced and equal to the transaction's TimeoutAction" +msgstr "Eine gemeinsame Transaktion kann nicht beendet werden, außer es wird erzwungen und ist gleich der TimeOutAction der Transaktion." + +#. Programmer's name for it: SFieldUnsupportedType +#: Vcl/ib.pas:232 +msgid "Unsupported Field Type" +msgstr "Nicht unterstützter Feldtyp" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/ib.pas:233 +msgid "Circular DataLink Reference" +msgstr "Zirkuläre DataLink-Verweis" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/ib.pas:234 +msgid "Empty SQL Statement" +msgstr "Leere SQL-Anweisung." + +#. Programmer's name for it: SIsASelectStatement +#: Vcl/ib.pas:235 +msgid "use Open for a Select Statement" +msgstr "Verwenden Sie Open für eine Select-Anweisung" + +#. Programmer's name for it: SRequiredParamNotSet +#: Vcl/ib.pas:236 +msgid "Required Param value not set" +msgstr "Wert für Required Param nicht gesetzt" + +#. Programmer's name for it: SNoStoredProcName +#: Vcl/ib.pas:237 +msgid "No Stored Procedure Name assigned" +msgstr "Stored Procedure wurde kein Name zugewiesen" + +#. Programmer's name for it: SIsAExecuteProcedure +#: Vcl/ib.pas:238 +msgid "use ExecProc for Procedure; use TQuery for Select procedures" +msgstr "Verwenden Sie ExecProc für Prozeduren; verwenden SieTQuery für Select-Prozeduren" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/ib.pas:239 +msgid "Update Failed" +msgstr "Aktualisierung nicht erfolgreich" + +#. Programmer's name for it: SNotCachedUpdates +#: Vcl/ib.pas:240 +msgid "CachedUpdates not enabled" +msgstr "CachedUpdates ist nicht aktiviert" + +#. Programmer's name for it: SNotLiveRequest +#: Vcl/ib.pas:241 +msgid "Request is not live - cannot modify" +msgstr "Die Anforderung ist nicht 'live' - Änderung nicht möglich." + +#. Programmer's name for it: SNoProvider +#: Vcl/ib.pas:242 +msgid "No Provider" +msgstr "Kein Provider" + +#. Programmer's name for it: SNoRecordsAffected +#: Vcl/ib.pas:243 +msgid "No Records Affected" +msgstr "Keine Datensätze betroffen" + +#. Programmer's name for it: SNoTableName +#: Vcl/ib.pas:244 +msgid "No Table Name assigned" +msgstr "Kein Tabellenname zugewiesen" + +#. Programmer's name for it: SCannotCreatePrimaryIndex +#: Vcl/ib.pas:245 +msgid "Cannot Create Primary Index; are created automatically" +msgstr "Primärindizes können nicht erzeugt werden, da sie automatisch erzeugt werden" + +#. Programmer's name for it: SCannotDropSystemIndex +#: Vcl/ib.pas:246 +msgid "Cannot Drop System Index" +msgstr "Systemindex kann nicht entfernt werden" + +#. Programmer's name for it: STableNameMismatch +#: Vcl/ib.pas:247 +msgid "Table Name Mismatch" +msgstr "Fehlende Übereinstimmung bei Tabellennamen" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/ib.pas:248 +msgid "Index Field Missing" +msgstr "Indexfeld fehlt" + +#. Programmer's name for it: SInvalidCancellation +#: Vcl/ib.pas:249 +msgid "Cannot Cancel events while processing" +msgstr "Während deren Bearbeitung können Ereignisse nicht abgebrochen werden" + +#. Programmer's name for it: SInvalidEvent +#: Vcl/ib.pas:250 +msgid "Invalid Event" +msgstr "Ungültiges Ereignis" + +#. Programmer's name for it: SMaximumEvents +#: Vcl/ib.pas:251 +msgid "Exceded Maximum Event limits" +msgstr "Das Maximum an Ereignissen wurde überschritten" + +#. Programmer's name for it: SNoEventsRegistered +#: Vcl/ib.pas:252 +msgid "No Events Registered" +msgstr "Es sind keine Ereignisse registriert" + +#. Programmer's name for it: SInvalidQueueing +#: Vcl/ib.pas:253 +msgid "Invalid Queueing" +msgstr "Ungültiges Queueing" + +#. Programmer's name for it: SInvalidRegistration +#: Vcl/ib.pas:254 +msgid "Invalid Registration" +msgstr "Ungültige Registrierung" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/ib.pas:255 +msgid "Invalid Batch Move" +msgstr "Ungültige Batch-Operation" + +#. Programmer's name for it: SSQLDialectInvalid +#: Vcl/ib.pas:256 +msgid "SQL Dialect Invalid" +msgstr "Ungültiger SQL-Dialekt" + +#. Programmer's name for it: SSPBConstantNotSupported +#: Vcl/ib.pas:257 +msgid "SPB Constant Not supported" +msgstr "SPB-Konstante nicht unterstützt" + +#. Programmer's name for it: SSPBConstantUnknown +#: Vcl/ib.pas:258 +msgid "SPB Constant Unknown" +msgstr "SPB-Konstante unbekannt" + +#. Programmer's name for it: SServiceActive +#: Vcl/ib.pas:259 +msgid "Cannot perform operation -- service is not attached" +msgstr "Operation kann nicht durchgeführt werden -- Es ist kein Service verbunden." + +#. Programmer's name for it: SServiceInActive +#: Vcl/ib.pas:260 +msgid "Cannot perform operation -- service is attached" +msgstr "Operation kann nicht durchgeführt werden -- Ein Service ist verbunden." + +#. Programmer's name for it: SServerNameMissing +#: Vcl/ib.pas:261 +msgid "Server Name Missing" +msgstr "Server-Name fehlt" + +#. Programmer's name for it: SQueryParamsError +#: Vcl/ib.pas:262 +msgid "Query Parameters missing or incorrect" +msgstr "Abfrageparameter fehlen oder sind nicht korrekt" + +#. Programmer's name for it: SStartParamsError +#: Vcl/ib.pas:263 +msgid "start Parameters missing or incorrect" +msgstr "start-Parameter fehlen oder sind nicht korrekt" + +#. Programmer's name for it: SOutputParsingError +#: Vcl/ib.pas:264 +msgid "Unexpected Output buffer value" +msgstr "Unerwarteter Wert für Ausgabepuffer" + +#. Programmer's name for it: SUseSpecificProcedures +#: Vcl/ib.pas:265 +msgid "Generic ServiceStart not applicable: Use Specific Procedures to set configuration params" +msgstr "Generisches ServiceStart ist hier nicht anwendbar: Verwenden Sie spezifische Prozeduren, um die Konfigurationsparameter zu setzen." + +#. Programmer's name for it: SSQLMonitorAlreadyPresent +#: Vcl/ib.pas:266 +msgid "SQL Monitor Instance is already present" +msgstr "Es gibt schon eine Instanz des SQL-Monitor" + +#. Programmer's name for it: SEOFInComment +#: Vcl/ibsql.pas:24 +msgid "EOF in comment detected" +msgstr "EOF im Kommentar gefunden" + +#. Programmer's name for it: SEOFInString +#: Vcl/ibsql.pas:25 +msgid "EOF in string detected" +msgstr "EOF im String gefunden" + +#. Programmer's name for it: SParamNameExpected +#: Vcl/ibsql.pas:26 +msgid "Parameter name expected" +msgstr "Parametername erwartet" + +#. Programmer's name for it: SCantPrintValue +#: Vcl/ibsqlmonitor.pas:24 +msgid "Cannot print value" +msgstr "Wert kann nicht gedruckt werden" + +#. Programmer's name for it: SEOFReached +#: Vcl/ibsqlmonitor.pas:25 +msgid "SEOFReached" +msgstr "SEOFReached" + +#. Programmer's name for it: SProviderNotExported +#: Vcl/midconst.pas:33 +msgid "Provider not exported: %s" +msgstr "Der Provider wurde nicht exportiert: %s" + +#. Programmer's name for it: SNoDataProvider +#: Vcl/midconst.pas:36 +msgid "Missing data provider or data packet" +msgstr "Fehlender Daten-Provider oder Datenpaket" + +#. Programmer's name for it: SInvalidDataPacket +#: Vcl/midconst.pas:37 +msgid "Invalid data packet" +msgstr "Ungültiges Datenpaket" + +#. Programmer's name for it: SRefreshError +#: Vcl/midconst.pas:38 +msgid "Must apply updates before refreshing data" +msgstr "Die Änderungen müssen vor der Aktualisierung der Daten übernommen werden" + +#. Programmer's name for it: SProviderInvalid +#: Vcl/midconst.pas:39 +msgid "Invalid provider. Provider was freed by the application server" +msgstr "Ungültiger Provider. Der Provider wurde bereits vom Anwendungsserver entladen" + +#. Programmer's name for it: SServerNameBlank +#: Vcl/midconst.pas:40 +msgid "Cannot connect, %s must contain a valid ServerName or ServerGUID" +msgstr "Es kann keine Verbindung hergestellt werden; %s muss einen gültigen Server-Namen oder eine ServerGUID enthalten" + +#. Programmer's name for it: SRepositoryIdBlank +#: Vcl/midconst.pas:41 +msgid "Cannot connect, %s must contain a valid repository id" +msgstr "Es kann keine Verbindung hergestellt werden; %s muss eine gültige Objketablagen-ID enthalten" + +#. Programmer's name for it: SAggsGroupingLevel +#: Vcl/midconst.pas:42 +msgid "Grouping level exceeds current index field count" +msgstr "Die Gruppierungsebene überschreitet die aktuelle Feldanzahl des Index" + +#. Programmer's name for it: SAggsNoSuchLevel +#: Vcl/midconst.pas:43 +msgid "Grouping level not defined" +msgstr "Die Gruppierungsebene ist nicht definiert" + +#. Programmer's name for it: SNoCircularReference +#: Vcl/midconst.pas:44 +msgid "Circular provider references not allowed" +msgstr "Zirkuläre Verweise von Providern sind nicht gestattet" + +#. Programmer's name for it: SErrorLoadingMidas +#: Vcl/midconst.pas:45 +msgid "Error loading MIDAS.DLL" +msgstr "Fehler beim Laden von MIDAS.DLL" + +#. Programmer's name for it: SCannotCreateDataSet +#: Vcl/midconst.pas:46 +msgid "No fields defined. Cannot create dataset" +msgstr "Es wurden keine Felder definiert. Datenmenge kann nicht erzeugt werden" + +#. Programmer's name for it: SSocketReadError +#: Vcl/midconst.pas:49 +msgid "Error reading from socket" +msgstr "Fehler beim Lesen aus Socket" + +#. Programmer's name for it: SInvalidProviderName +#: Vcl/midconst.pas:50 +msgid "Provider name \"%s\" was not recognized by the server" +msgstr "Der Provider-Name '%s' wurde vom Server nicht erkannt" + +#. Programmer's name for it: SBadVariantType +#: Vcl/midconst.pas:51 +msgid "Unsupported variant type: %s" +msgstr "Nicht unterstützter Variant-Typ: %s" + +#. Programmer's name for it: SInvalidAction +#: Vcl/midconst.pas:52 +msgid "Invalid action received: %d" +msgstr "Ungültige Aktion erhalten: %d" + +#. Programmer's name for it: SInvalidResponse +#: Vcl/midconst.pas:55 +msgid "Invalid response" +msgstr "Ungültige Rückmeldung" + +#. Programmer's name for it: STooManyRecordsModified +#: Vcl/midconst.pas:57 +msgid "Update affected more than 1 record." +msgstr "Die Aktualisierung betrifft mehr als 1 Datensatz." + +#. Programmer's name for it: SInvalidOptParamType +#: Vcl/midconst.pas:60 +msgid "Value cannot be stored in an optional parameter" +msgstr "Der Wert kann nicht als optionaler Parameter gespeichert werden" + +#. Programmer's name for it: SConstraintFailed +#: Vcl/midconst.pas:62 +msgid "Record or field constraint failed." +msgstr "Datensatz- oder Feldbedingung wurde geändert." + +#. Programmer's name for it: SField +#: Vcl/midconst.pas:63 +msgid "Field" +msgstr "Feld" + +#. Programmer's name for it: SReadOnlyProvider +#: Vcl/midconst.pas:64 +msgid "Cannot apply updates to a ReadOnly provider" +msgstr "Ein schreibgeschützter Provider kann nicht aktualisiert werden" + +#. Programmer's name for it: SNoKeySpecified +#: Vcl/midconst.pas:65 +msgid "Unable to find record. No key specified" +msgstr "Datensatz nicht gefunden; es wurde kein Schlüssel angegeben" + +#. Programmer's name for it: SFieldNameTooLong +#: Vcl/midconst.pas:67 +msgid "Field name cannot be longer then %d characters. Try setting ObjectView to True on the dataset" +msgstr "Der Feldname darf nicht länger als %d Zeichen sein. Sie sollten für die Datenmenge ObjectView auf True setzen" + +#. Programmer's name for it: SNoDataSets +#: Vcl/midconst.pas:68 +msgid "Cannot resolve to dataset when using nested datasets or references" +msgstr "Bei Datenmengen oder -referenzen kann in die Datenmenge nicht zurückgeschrieben werden" + +#. Programmer's name for it: SRecConstFail +#: Vcl/midconst.pas:69 +msgid "Preparation of record constraint failed with error \"%s\"" +msgstr "Die Vorbereitung der Datensatzbedingung konnte nicht durchgeführt werden; Fehler '%s'" + +#. Programmer's name for it: SFieldConstFail +#: Vcl/midconst.pas:70 +msgid "Preparation of field constraint failed with error \"%s\"" +msgstr "Die Vorbereitung der Feldbedingung konnte nicht durchgeführt werden; Fehler '%s'" + +#. Programmer's name for it: SDefExprFail +#: Vcl/midconst.pas:71 +msgid "Preparation of default expression failed with error \"%s\"" +msgstr "Die Vorbereitung des Standardausdrucks konnte nicht durchgeführt werden; Fehler '%s'" + +#. Programmer's name for it: SArrayElementError +#: Vcl/midconst.pas:72 +msgid "Array elements of type %s are not supported" +msgstr "Array-Elemente vom Typ %s werden nicht unterstützt" + +#. Programmer's name for it: SNoTableName +#: Vcl/midconst.pas:73 +msgid "Unable to resolve records. Table name not found." +msgstr "Datensätze können nicht zurückgeschrieben werden. Der Tabellenname wurde nicht gefunden." + +#. Programmer's name for it: SNoEditsAllowed +#: Vcl/midconst.pas:74 +msgid "Modifications are not allowed" +msgstr "Änderungen sind nicht gestattet" + +#. Programmer's name for it: SNoDeletesAllowed +#: Vcl/midconst.pas:75 +msgid "Deletes are not allowed" +msgstr "Löschen nicht gestattet" + +#. Programmer's name for it: SNoInsertsAllowed +#: Vcl/midconst.pas:76 +msgid "Inserts are not allowed" +msgstr "Einfügen nicht gestattet" + +#. Programmer's name for it: SCannotChangeCommandText +#: Vcl/midconst.pas:77 +msgid "CommandText changes are not allowed" +msgstr "Änderungen an CommandText sind nicht gestattet" + +#. Programmer's name for it: SNoServers +#: Vcl/midconst.pas:80 +msgid "No server available" +msgstr "Kein Server verfügbar" + +#. Programmer's name for it: SReturnError +#: Vcl/midconst.pas:83 +msgid "Expected return value not received" +msgstr "Der erwartete Rückgabewert wurde nicht empfangen" + +#. Programmer's name for it: SNoWinSock2 +#: Vcl/midconst.pas:84 +msgid "WinSock 2 must be installed to use the socket connection" +msgstr "Um Socket-Verbindungen verwenden zu können, muss WinSock2 installiert sein" + +#. Programmer's name for it: SURLRequired +#: Vcl/midconst.pas:87 +msgid "URL required" +msgstr "Es wird eine URL benötigt" + +#. Programmer's name for it: SDefaultURL +#: Vcl/midconst.pas:88 +msgid "http://server.company.com/scripts/httpsrvr.dll" +msgstr "http://server.company.com/scripts/httpsrvr.dll" + +#. Programmer's name for it: SInvalidURL +#: Vcl/midconst.pas:89 +msgid "URL must be in the form \"http://server.company.com/scripts/httpsrvr.dll\"" +msgstr "Die URL muss folgende Form besitzen: \"http://server.company.com/scripts/httpsrvr.dll\"" + +#. Programmer's name for it: SServerIsBusy +#: Vcl/midconst.pas:90 +msgid "Server is busy" +msgstr "Der Server ist ausgelastet" + +#. Programmer's name for it: SObjectNotAvailable +#: Vcl/midconst.pas:92 +msgid "Object not available: %s" +msgstr "Das Objekt ist nicht verfügbar: %s" + +#. Programmer's name for it: SBadPropValue +#: Vcl/oleconst.pas:15 +msgid "'%s' is not a valid property value" +msgstr "'%s' ist kein gültiger Wert für die Eigenschaft" + +#. Programmer's name for it: SCannotActivate +#: Vcl/oleconst.pas:16 +msgid "OLE control activation failed" +msgstr "Aktivierung des OLE-Steuerelements mißlungen" + +#. Programmer's name for it: SNoWindowHandle +#: Vcl/oleconst.pas:17 +msgid "Could not obtain OLE control window handle" +msgstr "Das Fenster-Handle des OLE-Elements nicht verfügbar" + +#. Programmer's name for it: SOleError +#: Vcl/oleconst.pas:18 +msgid "OLE error %.8x" +msgstr "OLE-Fehler %.8x" + +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:19 +msgid "Variant does not reference an OLE object" +msgstr "Variante referenziert kein OLE-Objekt" + +#. Programmer's name for it: SVarNotAutoObject +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:20 +msgid "Variant does not reference an automation object" +msgstr "Variante referenziert kein Automatisierungsobjekt" + +#. Programmer's name for it: SNoMethod +#: Vcl/oleconst.pas:21 +msgid "Method '%s' not supported by OLE object" +msgstr "Methode '%s' wird vom OLE-Objekt nicht unterstützt" + +#. Programmer's name for it: SLinkProperties +#: Vcl/oleconst.pas:22 +msgid "Link Properties" +msgstr "Verknüpfungseigenschaften" + +#. Programmer's name for it: SInvalidLinkSource +#: Vcl/oleconst.pas:23 +msgid "Cannot link to an invalid source." +msgstr "Zu einer ungültigen Quelle kann nicht verknüpft werden." + +#. Programmer's name for it: SCannotBreakLink +#: Vcl/oleconst.pas:24 +msgid "Break link operation is not supported." +msgstr "Operation zur Trennung der Verbindung nicht erlaubt." + +#. Programmer's name for it: SLinkedObject +#: Vcl/oleconst.pas:25 +msgid "Linked %s" +msgstr "Verknüpft %s" + +#. Programmer's name for it: SEmptyContainer +#: Vcl/oleconst.pas:26 +msgid "Operation not allowed on an empty OLE container" +msgstr "Operation mit einem leeren OLE-Container nicht zulässig" + +#. Programmer's name for it: SInvalidVerb +#: Vcl/oleconst.pas:27 +msgid "Invalid object verb" +msgstr "Ungültiges Objekt-Verb" + +#. Programmer's name for it: SPropDlgCaption +#: Vcl/oleconst.pas:28 +msgid "%s Properties" +msgstr "%s Eigenschaften" + +#. Programmer's name for it: SInvalidLicense +#: Vcl/oleconst.pas:30 +msgid "License information for %s is invalid" +msgstr "Lizenz-Information für %s ist ungültig" + +#. Programmer's name for it: SNotLicensed +#: Vcl/oleconst.pas:31 +msgid "License information for %s not found. You cannot use this control in design mode" +msgstr "Lizenz-Information für %s nicht gefunden. Sie können dieses Steuerelement im Entwurfsmodus nicht verwenden" + +#. Programmer's name for it: sNoRunningObject +#: Vcl/oleconst.pas:32 +msgid "Unable to retrieve a pointer to a running object registered with OLE for %s/%s" +msgstr "Es kann kein Zeiger auf ein ausgeführtes Objekt geholt werden, daß mit OLE für %s/%s registriert ist" + +#. Programmer's name for it: SServiceOnly +#: Vcl/scktcnst.pas:29 +msgid "The Socket Server can only be run as a service on NT 3.51 and prior" +msgstr "Der Socket-Server kann auf Win NT 3.51 und älter als Service ausgeführt werden" + +#. Programmer's name for it: SErrClose +#: Vcl/scktcnst.pas:30 +msgid "Cannot exit when there are active connections. Kill connections?" +msgstr "Das Programm kann nicht beendet werden, da noch aktive Verbindungen bestehen. Sollen diese Verbindungen abgebrochen werden?" + +#. Programmer's name for it: SErrChangeSettings +#: Vcl/scktcnst.pas:31 +msgid "Cannot change settings when there are active connections. Kill connections?" +msgstr "Die Einstellungen können nicht geändert werden, da noch aktive Verbindungen bestehen. Sollen diese Verbindungen abgebrochen werden?" + +#. Programmer's name for it: SQueryDisconnect +#: Vcl/scktcnst.pas:32 +msgid "Disconnecting clients can cause application errors. Continue?" +msgstr "Wenn die Verbindung zu den Clients getrennt wird, kann das zu Fehlern in der Anwendung führen. Weiter?" + +#. Programmer's name for it: SOpenError +#: Vcl/scktcnst.pas:33 +msgid "Error opening port %d with error: %s" +msgstr "Fehler beim Öffnen von Port %d. Fehler: %s" + +#. Programmer's name for it: SNotShown +#: Vcl/scktcnst.pas:35 +msgid "(Not Shown)" +msgstr "(Nicht angezeigt)" + +#. Programmer's name for it: SStatusline +#: Vcl/scktcnst.pas:37 +msgid "%d current connections" +msgstr "%d aktuelle Verbindungen" + +#. Programmer's name for it: SAlreadyRunning +#: Vcl/scktcnst.pas:38 +msgid "The Socket Server is already running" +msgstr "Der Socket-Server wird bereits ausgeführt" + +#. Programmer's name for it: SNotUntilRestart +#: Vcl/scktcnst.pas:39 +msgid "This change will not take affect until the Socket Server is restarted" +msgstr "Die Änderungen werden erst nach Neustart des Socket-Server wirksam" + +#. Programmer's name for it: sInvalidActionRegistration +#: Vcl/webconst.pas:15 +msgid "Invalid Action registration" +msgstr "Ungültige Aktionsregistrierung" + +#. Programmer's name for it: sDuplicateActionName +#: Vcl/webconst.pas:16 +msgid "Duplicate action name" +msgstr "Doppelter Aktionsname" + +#. Programmer's name for it: sOnlyOneDispatcher +#: Vcl/webconst.pas:17 +msgid "Only one WebDispatcher per form/data module" +msgstr "Nur ein WebDispatcher pro Formular/Datenmodul" + +#. Programmer's name for it: sHTTPItemName +#: Vcl/webconst.pas:18 +msgid "Name" +msgstr "Name" + +#. Programmer's name for it: sHTTPItemURI +#: Vcl/webconst.pas:19 +msgid "PathInfo" +msgstr "VerzInfo" + +#. Programmer's name for it: sHTTPItemEnabled +#: Vcl/webconst.pas:20 +msgid "Enabled" +msgstr "Aktiviert" + +#. Programmer's name for it: sHTTPItemProducer +#: Vcl/webconst.pas:22 +msgid "Producer" +msgstr "Produzent" + +#. Programmer's name for it: sTooManyColumns +#: Vcl/webconst.pas:26 +msgid "Too many table columns" +msgstr "Zu viele Tabellenspalten" + +#. Programmer's name for it: sFieldNameColumn +#: Vcl/webconst.pas:27 +msgid "Field Name" +msgstr "Feldname" + +#. Programmer's name for it: sFieldTypeColumn +#: Vcl/webconst.pas:28 +msgid "Field Type" +msgstr "Feldtyp" + +#. Programmer's name for it: SCorbaDllNotLoaded +#: Rtl/Corba/corbcnst.pas:15 +msgid "Unable to load CORBA libraries" +msgstr "Die CORBA-Bibliothek konnte nicht geladen werden" + +#. Programmer's name for it: SCorbaNotInitialized +#: Rtl/Corba/corbcnst.pas:16 +msgid "CORBA libraries are unavailable or not initialized" +msgstr "CORBA-Bibliotheken stehen nicht zur Verfügung oder sind nicht initialisiert" + +#. Programmer's name for it: SCorbaSkeletonNotRegistered +#: Rtl/Corba/corbcnst.pas:17 +msgid "CORBA server skeleton not registered for object %s" +msgstr "CORBA server skeleton nicht registriert für das Objekt %s" + +#. Programmer's name for it: SCorbaStubNotRegistered +#: Rtl/Corba/corbcnst.pas:18 +msgid "CORBA client stub not registered" +msgstr "CORBA-Client-Stub nicht registriert" + +#. Programmer's name for it: SCorbaInterfaceIDNotRegister +#: Rtl/Corba/corbcnst.pas:19 +msgid "CORBA interface not registered" +msgstr "CORBA-Schnittstelle nicht registriert" + +#. Programmer's name for it: SCorbaRepositoryIDNotRegistered +#: Rtl/Corba/corbcnst.pas:20 +msgid "CORBA Repository ID \"%s\" not registered" +msgstr "CORBA Repository ID \"%s\" nicht registriert" + +#. Programmer's name for it: SCorbaIncompleteFactory +#: Rtl/Corba/corbcnst.pas:21 +msgid "CORBA Factory did not implement CreateInterface" +msgstr "Die CORBA Factory implementiert CreateInterface nicht" + +#. Programmer's name for it: sInvalidTypeCast +#: Rtl/Corba/corbcnst.pas:24 +msgid "Variant cannot be converted to a CORBA Any" +msgstr "Variant kann nicht in CORBA Any konvertiert werden" + +#. Programmer's name for it: sNotCorbaObject +#: Rtl/Corba/corbcnst.pas:25 +msgid "Variant/Any not a CORBA object" +msgstr "Variant/Any ist kein CORBA-Objekt" + +#. Programmer's name for it: sParamTypeCast +#: Rtl/Corba/corbcnst.pas:26 +msgid "Parameter (%d) of method %s not of the correct type" +msgstr "Inkorrekter Typ des Parameters (%d) der Methode %s" + +#. Programmer's name for it: sParamOut +#: Rtl/Corba/corbcnst.pas:27 +msgid "Parameter (%d) of method %s is an out or in/out parameter and requires a variable reference" +msgstr "Der %d. Parameter der Methode %s ist ein out oder in/out Paramter und benötigt eine Referenz auf eine Variable" + +#. Programmer's name for it: sNoRepository +#: Rtl/Corba/corbcnst.pas:28 +msgid "Could not perform CORBA Dispatch, no interface repository found" +msgstr "CORBA Dispatch konnte nicht durchgeführt werden, da kein Schnittstellen-Repository gefunden wurde" + +#. Programmer's name for it: sInvalidParameterCount +#: Rtl/Corba/corbcnst.pas:29 +msgid "Incorrect number of parameters to method %s" +msgstr "Inkorrekte Parameteranzahl für Methode %s" + +#. Programmer's name for it: sMethodNotFound +#: Rtl/Corba/corbcnst.pas:30 +msgid "Method %s not found" +msgstr "Methode %s nicht gefunden" + +#. Programmer's name for it: sConnecting +#: Rtl/Corba/corbcnst.pas:31 +msgid "Connecting to CORBA server..." +msgstr "Verbindung mit CORBA-Server wird hergestellt..." + +#. Programmer's name for it: SCreateRegKeyError +#: Rtl/Sys/comconst.pas:15 +msgid "Error creating system registry entry" +msgstr "Fehler beim Erstellen eines Eintrages in der Systemregistrierung" + +#. Programmer's name for it: SObjectFactoryMissing +#: Rtl/Sys/comconst.pas:17 +msgid "Object factory for class %s missing" +msgstr "Der Objektgenerator für die Klasse %s fehlt" + +#. Programmer's name for it: STypeInfoMissing +#: Rtl/Sys/comconst.pas:18 +msgid "Type information missing for class %s" +msgstr "Für die Klasse %s fehlt die Typinformation" + +#. Programmer's name for it: SBadTypeInfo +#: Rtl/Sys/comconst.pas:19 +msgid "Incorrect type information for class %s" +msgstr "Falsche Typinformation für Klasse %s" + +#. Programmer's name for it: SDispIntfMissing +#: Rtl/Sys/comconst.pas:20 +msgid "Dispatch interface missing from class %s" +msgstr "Dispatch-Schnittstelle der Klasse %s fehlt" + +#. Programmer's name for it: SNoMethod +#: Rtl/Sys/comconst.pas:21 +msgid "Method '%s' not supported by automation object" +msgstr "Die Methode '%s' wird vom Automatisierungsobjekt nicht unterstützt" + +#. Programmer's name for it: SDCOMNotInstalled +#: Rtl/Sys/comconst.pas:23 +msgid "DCOM not installed" +msgstr "DCOM ist nicht installiert" + +#. Programmer's name for it: SDAXError +#: Rtl/Sys/comconst.pas:24 +msgid "DAX Error" +msgstr "DAX-Fehler" + +#. Programmer's name for it: SAutomationWarning +#: Rtl/Sys/comconst.pas:26 +msgid "COM Server Warning" +msgstr "Warnung des COM-Servers" + +#. Programmer's name for it: SNoCloseActiveServer1 +#: Rtl/Sys/comconst.pas:29 +msgid "There are still active COM objects in this application. One or more clients may have references to these objects, so manually closing " +msgstr "Diese Anwendung enthält noch aktive COM-Objekte.Mindestens ein Client verweist noch auf diese Objekte,so daß manuelles Schließen " + +#. Programmer's name for it: SNoCloseActiveServer2 +#: Rtl/Sys/comconst.pas:32 +msgid "" +"this application may cause those client application(s) to fail.\n" +"\n" +"Are you sure you want to close this application?" +msgstr "" +"dieser Anwendung dazu führen könnte, daß die Client-Anwendungennicht korrekt funktionieren.\n" +"\n" +"Sind Sie sicher, daß Sie diese Anwendung schließen möchten?" + +#. Programmer's name for it: SUnknown +#: Rtl/Sys/sysconst.pas:15 +msgid "" +msgstr "" + +#. Programmer's name for it: SInvalidInteger +#: Rtl/Sys/sysconst.pas:16 +msgid "'%s' is not a valid integer value" +msgstr "'%s' ist kein gültiger Integerwert" + +#. Programmer's name for it: SInvalidFloat +#: Rtl/Sys/sysconst.pas:17 +msgid "'%s' is not a valid floating point value" +msgstr "'%s' ist kein gültiger Gleitkommawert" + +#. Programmer's name for it: SInvalidDate +#: Rtl/Sys/sysconst.pas:18 +msgid "'%s' is not a valid date" +msgstr "'%s' ist kein gültiges Datum" + +#. Programmer's name for it: SInvalidTime +#: Rtl/Sys/sysconst.pas:19 +msgid "'%s' is not a valid time" +msgstr "'%s' ist keine gültige Uhrzeit" + +#. Programmer's name for it: SInvalidDateTime +#: Rtl/Sys/sysconst.pas:20 +msgid "'%s' is not a valid date and time" +msgstr "'%s' ist keine gültige Datums- und Uhrzeitangabe" + +#. Programmer's name for it: SOutOfMemory +#: Rtl/Sys/sysconst.pas:23 +msgid "Out of memory" +msgstr "Zu wenig Arbeitsspeicher" + +#. Programmer's name for it: SInOutError +#: Rtl/Sys/sysconst.pas:24 +msgid "I/O error %d" +msgstr "E/A-Fehler %d" + +#. Programmer's name for it: SFileNotFound +#: Rtl/Sys/sysconst.pas:25 +msgid "File not found" +msgstr "Datei nicht gefunden" + +#. Programmer's name for it: SInvalidFilename +#: Rtl/Sys/sysconst.pas:26 +msgid "Invalid filename" +msgstr "Ungültiger Dateiname" + +#. Programmer's name for it: STooManyOpenFiles +#: Rtl/Sys/sysconst.pas:27 +msgid "Too many open files" +msgstr "Zu viele geöffnete Dateien" + +#. Programmer's name for it: SAccessDenied +#: Rtl/Sys/sysconst.pas:28 +msgid "File access denied" +msgstr "Dateizugriff verweigert" + +#. Programmer's name for it: SEndOfFile +#: Rtl/Sys/sysconst.pas:29 +msgid "Read beyond end of file" +msgstr "Versuch hinter dem Dateiende zu lesen" + +#. Programmer's name for it: SDiskFull +#: Rtl/Sys/sysconst.pas:30 +msgid "Disk full" +msgstr "Zu wenig Speicherplatz" + +#. Programmer's name for it: SInvalidInput +#: Rtl/Sys/sysconst.pas:31 +msgid "Invalid numeric input" +msgstr "Ungültige numerische Eingabe" + +#. Programmer's name for it: SDivByZero +#: Rtl/Sys/sysconst.pas:32 +msgid "Division by zero" +msgstr "Division durch Null" + +#. Programmer's name for it: SRangeError +#: Rtl/Sys/sysconst.pas:33 +msgid "Range check error" +msgstr "Fehler bei Bereichsprüfung" + +#. Programmer's name for it: SIntOverflow +#: Rtl/Sys/sysconst.pas:34 +msgid "Integer overflow" +msgstr "Integerüberlauf" + +#. Programmer's name for it: SInvalidOp +#: Rtl/Sys/sysconst.pas:35 +msgid "Invalid floating point operation" +msgstr "Ungültige Gleitkommaoperation" + +#. Programmer's name for it: SZeroDivide +#: Rtl/Sys/sysconst.pas:36 +msgid "Floating point division by zero" +msgstr "Gleitkommadivision durch Null" + +#. Programmer's name for it: SOverflow +#: Rtl/Sys/sysconst.pas:37 +msgid "Floating point overflow" +msgstr "Gleitkommaüberlauf" + +#. Programmer's name for it: SUnderflow +#: Rtl/Sys/sysconst.pas:38 +msgid "Floating point underflow" +msgstr "Gleitkommaunterlauf" + +#. Programmer's name for it: SInvalidPointer +#: Rtl/Sys/sysconst.pas:39 +msgid "Invalid pointer operation" +msgstr "Ungültige Zeigeroperation" + +#. Programmer's name for it: SInvalidCast +#: Rtl/Sys/sysconst.pas:40 +msgid "Invalid class typecast" +msgstr "Ungültige Typumwandlung" + +#. Programmer's name for it: SAccessViolation +#: Rtl/Sys/sysconst.pas:41 +msgid "Access violation at address %p. %s of address %p" +msgstr "Zugriffsverletzung bei Adresse %p. %s von Adresse %p" + +#. Programmer's name for it: SStackOverflow +#: Rtl/Sys/sysconst.pas:42 +msgid "Stack overflow" +msgstr "Stack-Überlauf" + +#. Programmer's name for it: SControlC +#: Rtl/Sys/sysconst.pas:43 +msgid "Control-C hit" +msgstr "Strg+C gedrückt" + +#. Programmer's name for it: SPrivilege +#: Rtl/Sys/sysconst.pas:44 +msgid "Privileged instruction" +msgstr "Privilegierte Anweisung" + +#. Programmer's name for it: SOperationAborted +#: Rtl/Sys/sysconst.pas:45 +msgid "Operation aborted" +msgstr "Operation abgebrochen" + +#. Programmer's name for it: SException +#: Rtl/Sys/sysconst.pas:46 +msgid "" +"Exception %s in module %s at %p.\n" +"%s%s" +msgstr "" +"Exception %s im Modul %s bei %p.\n" +"%s%s" + +#. Programmer's name for it: SExceptTitle +#: Rtl/Sys/sysconst.pas:47 +msgid "Application Error" +msgstr "Anwendungsfehler" + +#. Programmer's name for it: SInvalidFormat +#: Rtl/Sys/sysconst.pas:48 +msgid "Format '%s' invalid or incompatible with argument" +msgstr "Format '%s' ungültig oder nicht kompatibel mit Argument" + +#. Programmer's name for it: SArgumentMissing +#: Rtl/Sys/sysconst.pas:49 +msgid "No argument for format '%s'" +msgstr "Kein Argument für Format '%s'" + +#. Programmer's name for it: SInvalidVarCast +#: Rtl/Sys/sysconst.pas:50 +msgid "Invalid variant type conversion" +msgstr "Ungültige Variant-Typumwandlung" + +#. Programmer's name for it: SInvalidVarOp +#: Rtl/Sys/sysconst.pas:51 +msgid "Invalid variant operation" +msgstr "Ungültige Variant-Operation" + +#. Programmer's name for it: SDispatchError +#: Rtl/Sys/sysconst.pas:52 +msgid "Variant method calls not supported" +msgstr "Variant-Methodenaufruf nicht unterstützt" + +#. Programmer's name for it: SResultTooLong +#: Rtl/Sys/sysconst.pas:55 +msgid "Format result longer than 4096 characters" +msgstr "Formatergebnis länger als 4096 Zeichen" + +#. Programmer's name for it: SFormatTooLong +#: Rtl/Sys/sysconst.pas:56 +msgid "Format string too long" +msgstr "Format-String zu lang" + +#. Programmer's name for it: SVarArrayCreate +#: Rtl/Sys/sysconst.pas:57 +msgid "Error creating variant array" +msgstr "Fehler beim Erstellen des Variant-Arrays" + +#. Programmer's name for it: SVarNotArray +#: Rtl/Sys/sysconst.pas:58 +msgid "Variant is not an array" +msgstr "Variant ist kein Array" + +#. Programmer's name for it: SVarArrayBounds +#: Rtl/Sys/sysconst.pas:59 +msgid "Variant array index out of bounds" +msgstr "Index des Variant-Arrays außerhalb des Bereichs" + +#. Programmer's name for it: SExternalException +#: Rtl/Sys/sysconst.pas:60 +msgid "External exception %x" +msgstr "Externe Exception %x" + +#. Programmer's name for it: SAssertionFailed +#: Rtl/Sys/sysconst.pas:61 +msgid "Assertion failed" +msgstr "Auswertung von assert fehlgeschlagen" + +#. Programmer's name for it: SIntfCastError +#: Rtl/Sys/sysconst.pas:62 +msgid "Interface not supported" +msgstr "Schnittstelle nicht unterstützt" + +#. Programmer's name for it: SSafecallException +#: Rtl/Sys/sysconst.pas:63 +msgid "Exception in safecall method" +msgstr "Exception in safecall-Methode" + +#. Programmer's name for it: SAssertError +#: Rtl/Sys/sysconst.pas:64 +msgid "%s (%s, line %d)" +msgstr "%s (%s, Zeile %d)" + +#. Programmer's name for it: SAbstractError +#: Rtl/Sys/sysconst.pas:65 +msgid "Abstract Error" +msgstr "Abstrakter Fehler" + +#. Programmer's name for it: SModuleAccessViolation +#: Rtl/Sys/sysconst.pas:66 +msgid "Access violation at address %p in module '%s'. %s of address %p" +msgstr "Zugriffsverletzung bei Adresse %p in Modul '%s'. %s von Adresse %p" + +#. Programmer's name for it: SCannotReadPackageInfo +#: Rtl/Sys/sysconst.pas:67 +msgid "Cannot access package information for package '%s'" +msgstr "Zugriff auf Package-Informationen von '%s' nicht möglich" + +#. Programmer's name for it: sErrorLoadingPackage +#: Rtl/Sys/sysconst.pas:68 +msgid "" +"Can't load package %s.\n" +"%s" +msgstr "" +"Package %s kann nicht geladen werden.\n" +"%s" + +#. Programmer's name for it: SInvalidPackageFile +#: Rtl/Sys/sysconst.pas:69 +msgid "Invalid package file '%s'" +msgstr "Ungültige Package-Datei '%s'" + +#. Programmer's name for it: SInvalidPackageHandle +#: Rtl/Sys/sysconst.pas:70 +msgid "Invalid package handle" +msgstr "Ungültiges Package-Handle" + +#. Programmer's name for it: SDuplicatePackageUnit +#: Rtl/Sys/sysconst.pas:72 +msgid "Cannot load package '%s.' It contains unit '%s,';which is also contained in package '%s'" +msgstr "Package '%s' kann nicht geladen werden. Es enthält die Unit '%s', die auch im Package '%s' enthalten ist" + +#. Programmer's name for it: SWin32Error +#: Rtl/Sys/sysconst.pas:73 +msgid "" +"Win32 Error. Code: %d.\n" +"%s" +msgstr "" +"Win32 Fehler.\tCode: %d.\n" +"%s" + +#. Programmer's name for it: SUnkWin32Error +#: Rtl/Sys/sysconst.pas:74 +msgid "A Win32 API function failed" +msgstr "Fehler bei einer Win32 API-Funktion" + +#. Programmer's name for it: SNL +#: Rtl/Sys/sysconst.pas:75 +msgid "Application is not licensed to use this feature" +msgstr "Die Anwendung ist für diese Funktion nicht lizenziert." + +#. Programmer's name for it: SShortMonthNameJan +#: Rtl/Sys/sysconst.pas:77 +msgid "Jan" +msgstr "Jan" + +#. Programmer's name for it: SShortMonthNameFeb +#: Rtl/Sys/sysconst.pas:78 +msgid "Feb" +msgstr "Feb" + +#. Programmer's name for it: SShortMonthNameMar +#: Rtl/Sys/sysconst.pas:79 +msgid "Mar" +msgstr "Mär" + +#. Programmer's name for it: SShortMonthNameApr +#: Rtl/Sys/sysconst.pas:80 +msgid "Apr" +msgstr "Apr" + +#. Programmer's name for it: SShortMonthNameMay +#. Programmer's name for it: SLongMonthNameMay +#: Rtl/Sys/sysconst.pas:81 +msgid "May" +msgstr "Mai" + +#. Programmer's name for it: SShortMonthNameJun +#: Rtl/Sys/sysconst.pas:82 +msgid "Jun" +msgstr "Jun" + +#. Programmer's name for it: SShortMonthNameJul +#: Rtl/Sys/sysconst.pas:83 +msgid "Jul" +msgstr "Jul" + +#. Programmer's name for it: SShortMonthNameAug +#: Rtl/Sys/sysconst.pas:84 +msgid "Aug" +msgstr "Aug" + +#. Programmer's name for it: SShortMonthNameSep +#: Rtl/Sys/sysconst.pas:85 +msgid "Sep" +msgstr "Sep" + +#. Programmer's name for it: SShortMonthNameOct +#: Rtl/Sys/sysconst.pas:86 +msgid "Oct" +msgstr "Okt" + +#. Programmer's name for it: SShortMonthNameNov +#: Rtl/Sys/sysconst.pas:87 +msgid "Nov" +msgstr "Nov" + +#. Programmer's name for it: SShortMonthNameDec +#: Rtl/Sys/sysconst.pas:88 +msgid "Dec" +msgstr "Dez" + +#. Programmer's name for it: SLongMonthNameJan +#: Rtl/Sys/sysconst.pas:90 +msgid "January" +msgstr "Januar" + +#. Programmer's name for it: SLongMonthNameFeb +#: Rtl/Sys/sysconst.pas:91 +msgid "February" +msgstr "Februar" + +#. Programmer's name for it: SLongMonthNameMar +#: Rtl/Sys/sysconst.pas:92 +msgid "March" +msgstr "März" + +#. Programmer's name for it: SLongMonthNameApr +#: Rtl/Sys/sysconst.pas:93 +msgid "April" +msgstr "April" + +#. Programmer's name for it: SLongMonthNameJun +#: Rtl/Sys/sysconst.pas:95 +msgid "June" +msgstr "Juni" + +#. Programmer's name for it: SLongMonthNameJul +#: Rtl/Sys/sysconst.pas:96 +msgid "July" +msgstr "Juli" + +#. Programmer's name for it: SLongMonthNameAug +#: Rtl/Sys/sysconst.pas:97 +msgid "August" +msgstr "August" + +#. Programmer's name for it: SLongMonthNameSep +#: Rtl/Sys/sysconst.pas:98 +msgid "September" +msgstr "September" + +#. Programmer's name for it: SLongMonthNameOct +#: Rtl/Sys/sysconst.pas:99 +msgid "October" +msgstr "Oktober" + +#. Programmer's name for it: SLongMonthNameNov +#: Rtl/Sys/sysconst.pas:100 +msgid "November" +msgstr "November" + +#. Programmer's name for it: SLongMonthNameDec +#: Rtl/Sys/sysconst.pas:101 +msgid "December" +msgstr "Dezember" + +#. Programmer's name for it: SShortDayNameSun +#: Rtl/Sys/sysconst.pas:103 +msgid "Sun" +msgstr "So" + +#. Programmer's name for it: SShortDayNameMon +#: Rtl/Sys/sysconst.pas:104 +msgid "Mon" +msgstr "Mo" + +#. Programmer's name for it: SShortDayNameTue +#: Rtl/Sys/sysconst.pas:105 +msgid "Tue" +msgstr "Di" + +#. Programmer's name for it: SShortDayNameWed +#: Rtl/Sys/sysconst.pas:106 +msgid "Wed" +msgstr "Mi" + +#. Programmer's name for it: SShortDayNameThu +#: Rtl/Sys/sysconst.pas:107 +msgid "Thu" +msgstr "Do" + +#. Programmer's name for it: SShortDayNameFri +#: Rtl/Sys/sysconst.pas:108 +msgid "Fri" +msgstr "Fr" + +#. Programmer's name for it: SShortDayNameSat +#: Rtl/Sys/sysconst.pas:109 +msgid "Sat" +msgstr "Sa" + +#. Programmer's name for it: SLongDayNameSun +#: Rtl/Sys/sysconst.pas:111 +msgid "Sunday" +msgstr "Sonntag" + +#. Programmer's name for it: SLongDayNameMon +#: Rtl/Sys/sysconst.pas:112 +msgid "Monday" +msgstr "Montag" + +#. Programmer's name for it: SLongDayNameTue +#: Rtl/Sys/sysconst.pas:113 +msgid "Tuesday" +msgstr "Dienstag" + +#. Programmer's name for it: SLongDayNameWed +#: Rtl/Sys/sysconst.pas:114 +msgid "Wednesday" +msgstr "Mittwoch" + +#. Programmer's name for it: SLongDayNameThu +#: Rtl/Sys/sysconst.pas:115 +msgid "Thursday" +msgstr "Donnerstag" + +#. Programmer's name for it: SLongDayNameFri +#: Rtl/Sys/sysconst.pas:116 +msgid "Friday" +msgstr "Freitag" + +#. Programmer's name for it: SLongDayNameSat +#: Rtl/Sys/sysconst.pas:117 +msgid "Saturday" +msgstr "Samstag" + +#. Programmer's name: FONT 8 +#: Vcl/extdlgs.rc:14 +msgid "MS Sans Serif" +msgstr "MS Sans Serif" + +#. DSSCubeEditor..Caption +#: Decision Cube/mxdcube.dfm:6 +msgid "Decision Cube Editor" +msgstr "Editor für Entscheidungswürfel" + +#. DSSCubeEditor..Pager..DimensionInfo..Caption +#: Decision Cube/mxdcube.dfm:24 +msgid "Dimension Settings" +msgstr "Dimensionseinstellungen" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionLabel..Caption +#: Decision Cube/mxdcube.dfm:31 +msgid "Display &Name" +msgstr "A&nzeige" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveLabel..Caption +#: Decision Cube/mxdcube.dfm:40 +msgid "&Active Type" +msgstr "A&ktivität" + +#. DSSCubeEditor..Pager..DimensionInfo..BinLabel..Caption +#: Decision Cube/mxdcube.dfm:49 +msgid "&Grouping" +msgstr "&Gruppierung" + +#. DSSCubeEditor..Pager..DimensionInfo..StartLabel..Caption +#: Decision Cube/mxdcube.dfm:58 +msgid "&Initial Value" +msgstr "&Anfangswert" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeLabel..Caption +#: Decision Cube/mxdcube.dfm:67 +msgid "&Type" +msgstr "&Typ" + +#. DSSCubeEditor..Pager..DimensionInfo..Label1..Caption +#: Decision Cube/mxdcube.dfm:76 +msgid "Available &Fields" +msgstr "Verfügbare &Felder:" + +#. DSSCubeEditor..Pager..DimensionInfo..Label2..Caption +#: Decision Cube/mxdcube.dfm:85 +msgid "For&mat" +msgstr "For&mat" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameLabel..Caption +#: Decision Cube/mxdcube.dfm:102 +msgid "&Base Field" +msgstr "&Basisfeld" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionEdit..Text +#: Decision Cube/mxdcube.dfm:122 +msgid "CaptionEdit" +msgstr "CaptionEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Hint +#: Decision Cube/mxdcube.dfm:130 +msgid "Control of when the information for this field is loaded" +msgstr "Steuerung wenn die Information für dieses Feld geladen ist" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:136 +msgid "" +"Active\n" +"As Needed\n" +"Inactive\n" +msgstr "" +"Aktiv\n" +"Bei Bedarf\n" +"Inaktiv\n" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Text +#: Decision Cube/mxdcube.dfm:139 +msgid "ActiveEdit" +msgstr "ActiveEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Hint +#: Decision Cube/mxdcube.dfm:147 +msgid "Group values for this field into ranges" +msgstr "Gruppiere Werte dieses Feldes in Bereiche" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:155 +msgid "" +"None\n" +"Year\n" +"Quarter\n" +"Month\n" +"Single Value\n" +msgstr "" +"Keines\n" +"Jahr\n" +"Quartal\n" +"Monat\n" +"Einzelwert\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Text +#: Decision Cube/mxdcube.dfm:158 +msgid "BinEdit" +msgstr "BinEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:176 +msgid "" +"Dimension\n" +"Sum\n" +"Count\n" +"Average\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unknown\n" +msgstr "" +"Ausmaß\n" +"Summe\n" +"Anzahl\n" +"Durchschnitt\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unbekannt\n" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit..Text +#: Decision Cube/mxdcube.dfm:179 +msgid "TypeEdit" +msgstr "TypeEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..FormatEdit..Text +#: Decision Cube/mxdcube.dfm:190 +msgid "FormatEdit" +msgstr "FormatEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..StartEdit....Height +#: Decision Cube/mxdcube.dfm:201 +msgid "Starting value for date ranges, Intial value for single valued dimensions\n" +msgstr "Startwert für Datumsbereich, Startwert für eindimensionale Einheiten\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit....Height +#: Decision Cube/mxdcube.dfm:214 +msgid "Fieldname (for a summary, the original field used to calculate the summary)\n" +msgstr "Feldname (für die Zusammanfassung, das ursprüngliche Feld wird für die Kalkulation der Summe benutzt)\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit..Text +#: Decision Cube/mxdcube.dfm:217 +msgid "BaseNameEdit" +msgstr "BaseNameEdit" + +#. DSSCubeEditor..Pager..MemoryControl..Caption +#: Decision Cube/mxdcube.dfm:223 +msgid "Memory Control" +msgstr "Speicherkontrolle" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Hint +#: Decision Cube/mxdcube.dfm:229 +msgid "Control whether to load the decision cube at design time" +msgstr "Steuerung, ob der Decision Cube zur Laufzeit geladen wird" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Caption +#: Decision Cube/mxdcube.dfm:230 +msgid "Designer Data Options" +msgstr "Optionen für Designer Daten" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioMetaData..Caption +#: Decision Cube/mxdcube.dfm:239 +msgid "Display Dimension &Names" +msgstr "Maßeinheiten a&nzeigen" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioDimensionData..Caption +#: Decision Cube/mxdcube.dfm:250 +msgid "Display Names and &Values" +msgstr "Namen und &Werte anzeigen" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioAllData..Caption +#: Decision Cube/mxdcube.dfm:259 +msgid "Display Names, Values, and &Totals" +msgstr "Namen, Wer&te und Summen anzeigen" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioNoData..Caption +#: Decision Cube/mxdcube.dfm:268 +msgid "&Run Time Display Only" +msgstr "Nu&r Laufzeitanzeige" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Caption +#: Decision Cube/mxdcube.dfm:278 +msgid "Cube Maximums" +msgstr "Cube Maxima" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label4..Caption +#: Decision Cube/mxdcube.dfm:304 +msgid "Active" +msgstr "Aktiv" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label7..Caption +#: Decision Cube/mxdcube.dfm:312 +msgid "Active+Needed" +msgstr "Aktiv+Benötigt" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label9..Caption +#: Decision Cube/mxdcube.dfm:320 +msgid "&Dimensions" +msgstr "&Maße" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label6..Caption +#: Decision Cube/mxdcube.dfm:348 +msgid "&Summaries" +msgstr "Zu&sammenfassungen" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label12..Caption +#: Decision Cube/mxdcube.dfm:358 +msgid "&Cells" +msgstr "&Zellen" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label5..Caption +#: Decision Cube/mxdcube.dfm:376 +msgid "Maximum" +msgstr "Maximum" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label3..Caption +#: Decision Cube/mxdcube.dfm:384 +msgid "Current" +msgstr "Aktuell" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxDims....Height +#: Decision Cube/mxdcube.dfm:421 +msgid "Limit on the number of dimensions which can be loaded at one time\n" +msgstr "Limitierung der Anzahl der Einheiten, die gleichzeitig geladen werden können\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxSums..Hint +#: Decision Cube/mxdcube.dfm:430 +msgid "Limit on the number of summaries which can be loaded at one time" +msgstr "Limitierung der Anzahl der Zusammanfassungen, die gleichzeitig geladen werden können" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxCells....Height +#: Decision Cube/mxdcube.dfm:443 +msgid "Limit on the number of storage cells which can be loaded at one time\n" +msgstr "Limitierung der Anzahl der Speicherzellen, die gleichzeitig geladen werden können\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Hint +#: Decision Cube/mxdcube.dfm:452 +msgid "Run a query to fetch information required to estimate cell usage" +msgstr "Abfrage zum Einholen von notwendigen Informationen starten, um den Zellenverbrauch abzuschätzen" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Caption +#: Decision Cube/mxdcube.dfm:453 +msgid "&Get Cell Counts" +msgstr "&Ermittle Zellenanzahl" + +#. DimEditor..Caption +#. FieldsEditor..Caption +#: Decision Cube/mxdesign.dfm:6 +#: Editors/dsdesign.dfm:8 +msgid "Form1.Table1" +msgstr "Form1.Table1" + +#. SQLWindow..Caption +#: Decision Cube/mxdsql.dfm:6 +msgid "Form2" +msgstr "Form2" + +#. SQLWindow..Memo1....Lines.Strings +#: Decision Cube/mxdsql.dfm:32 +msgid "Memo1\n" +msgstr "Memo1\n" + +#. DSSQueryEditor..Caption +#: Decision Cube/mxdssqry.dfm:6 +msgid "Decision Query Editor" +msgstr "Editor für Entscheidungsabfrage" + +#. DSSQueryEditor..Pager..Dimensions..Caption +#: Decision Cube/mxdssqry.dfm:23 +msgid "Dimensions/Summaries" +msgstr "Maße/Zusammenfassungen" + +#. DSSQueryEditor..Pager..Dimensions..Label2..Caption +#: Decision Cube/mxdssqry.dfm:30 +msgid "&Dimensions:" +msgstr "&Maße:" + +#. DSSQueryEditor..Pager..Dimensions..Label3..Caption +#: Decision Cube/mxdssqry.dfm:39 +msgid "&Summaries:" +msgstr "&Zusammenfassungen:" + +#. DSSQueryEditor..Pager..Dimensions..Label4..Caption +#: Decision Cube/mxdssqry.dfm:48 +msgid "&List of Available Fields:" +msgstr "&Liste der verfügbaren Felder:" + +#. DSSQueryEditor..Pager..Dimensions..Label5..Caption +#: Decision Cube/mxdssqry.dfm:57 +msgid "&Table:" +msgstr "&Tabelle:" + +#. DSSQueryEditor..Pager..Dimensions..Label6..Caption +#: Decision Cube/mxdssqry.dfm:66 +msgid "Databas&e:" +msgstr "Dat&enbank:" + +#. DSSQueryEditor..Pager..Dimensions..Label7..Caption +#. CollectionEditor..ActionList1..AddCmd..Caption +#. LinkFields..AddButton..Caption +#. SocketForm..MainMenu1..miPorts..miAdd..Caption +#: Decision Cube/mxdssqry.dfm:76 +#: Editors/fldlinks.dfm:114 +#: Vcl/scktmain.dfm:345 +msgid "&Add" +msgstr "Hinzu&fügen" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Hint +#: Decision Cube/mxdssqry.dfm:129 +msgid "List all fields or List only the fields in the query" +msgstr "&Alle Felder" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Caption +#: Decision Cube/mxdssqry.dfm:130 +msgid "All &Fields" +msgstr "Alle &Felder" + +#. DSSQueryEditor..Pager..Dimensions..TableCombo..Hint +#: Decision Cube/mxdssqry.dfm:141 +msgid "Start a new query using a table from the database" +msgstr "Starte eine neue Abfrage unter Benutzung einer Tabelle der Datenbank" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Hint +#: Decision Cube/mxdssqry.dfm:251 +msgid "Use count(*) to calculate averages (counts null values)" +msgstr "Benutze count(*), um den Durchschnitt zu ermitteln (zählt Leerwerte)" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Caption +#: Decision Cube/mxdssqry.dfm:252 +msgid "Count (*) for Averages" +msgstr "Zur Berechnung von Mittelwerten count(*) verwenden (zählt Nullwerte mit)" + +#. DSSQueryEditor..Pager..Query..Caption +#: Decision Cube/mxdssqry.dfm:261 +msgid "SQL Query" +msgstr "SQL-Abfrage" + +#. DSSQueryEditor..Pager..Query..Label1..Caption +#: Decision Cube/mxdssqry.dfm:268 +msgid "&Query Text:" +msgstr "&Abfragetext:" + +#. DSSQueryEditor..Pager..Query..CancelQryMod..Caption +#: Decision Cube/mxdssqry.dfm:287 +msgid "&Cancel Edit" +msgstr "Bearbeiten &abbrechen" + +#. DSSQueryEditor..Pager..Query..EditQry..Hint +#: Decision Cube/mxdssqry.dfm:296 +msgid "Type in the query directly" +msgstr "Geben Sie die Abfrage direkt ein" + +#. DSSQueryEditor..VQB..Hint +#: Decision Cube/mxdssqry.dfm:340 +msgid "Add/Join Tables and Create Field List with SQL Builder" +msgstr "Add/Join Tables und Create Field List mit dem SQL Builder" + +#. DSSQueryEditor..VQB..Caption +#: Decision Cube/mxdssqry.dfm:341 +msgid "SQL &Builder ..." +msgstr "SQL-&Builder..." + +#. DSSQueryEditor..AggPopup..count1..Caption +#: Decision Cube/mxdssqry.dfm:351 +msgid "&sum" +msgstr "&Summe" + +#. DSSQueryEditor..AggPopup..count2..Caption +#: Decision Cube/mxdssqry.dfm:355 +msgid "&count" +msgstr "&Anzahl" + +#. DSSQueryEditor..AggPopup..average1..Caption +#: Decision Cube/mxdssqry.dfm:359 +msgid "&average" +msgstr "&durchschnittlich" + +#. ProgressDialog..Caption +#: Decision Cube/mxpbar.dfm:6 +msgid "ProgressDialog" +msgstr "Fortschrittsanzeige" + +#. ProgressDialog..CancelButton..Caption +#. DataBindForm..CancelBtn..Caption +#: Decision Cube/mxpbar.dfm:29 +msgid "&Cancel" +msgstr "&Abbrechen" + +#. ProgressDialog..StatusText..Caption +#: Decision Cube/mxpbar.dfm:40 +msgid "StatusText" +msgstr "StatusText" + +#. ConnEditForm..SourceofConnection..Caption +#: Property Editors/adoconed.dfm:49 +msgid " Source of Connection " +msgstr " Quelle der Verbindung " + +#. ConnEditForm..SourceofConnection..UseDataLinkFile..Caption +#: Property Editors/adoconed.dfm:57 +msgid "Use Data &Link File" +msgstr "D&atenverknüpfungsdatei verwenden" + +#. ConnEditForm..SourceofConnection..Browse..Caption +#: Property Editors/adoconed.dfm:77 +msgid "&Browse..." +msgstr "&Durchsuchen..." + +#. ConnEditForm..SourceofConnection..UseConnectionString..Caption +#: Property Editors/adoconed.dfm:87 +msgid "Use &Connection String" +msgstr "&Verbindungs-String verwenden" + +#. ConnEditForm..SourceofConnection..Build..Caption +#: Property Editors/adoconed.dfm:105 +msgid "B&uild..." +msgstr "A&ufbauen..." + +#. ClientDataForm..Caption +#: Property Editors/cdsedit.dfm:6 +msgid "Client DataSet Data" +msgstr "Daten der Client-Datenmenge" + +#. ClientDataForm..GroupBox1..Caption +#: Property Editors/cdsedit.dfm:19 +msgid " Assign Data From " +msgstr " Daten zuweisen von " + +#. CollectionEditor..Caption +#: Property Editors/colnedit.dfm:10 +msgid "CollectionEditor" +msgstr "CollectionEditor" + +#. CollectionEditor..ToolBar1..ToolButton3..Caption +#: Property Editors/colnedit.dfm:41 +msgid "ToolButton3" +msgstr "ToolButton3" + +#. CollectionEditor..PopupMenu1..N2..Caption +#. FieldsEditor..LocalMenu..N1..Caption +#. SocketForm..PopupMenu..N1..Caption +#. SocketForm..MainMenu1..miPorts..N3..Caption +#. SocketForm..MainMenu1..Connections1..N2..Caption +#: Property Editors/colnedit.dfm:183 +#: Vcl/scktmain.dfm:324 +#: Vcl/scktmain.dfm:352 +#: Vcl/scktmain.dfm:368 +msgid "-" +msgstr "-" + +#. CollectionEditor..ActionList1..AddCmd..Hint +#: Property Editors/colnedit.dfm:190 +msgid "Add New" +msgstr "Neue hinzufügen" + +#. CollectionEditor..ActionList1..DeleteCmd..Caption +#. DataBindForm..Panel1..DeleteBtn..Caption +#. FieldsEditor..LocalMenu..DeleteItem..Caption +#. LinkFields..DeleteButton..Caption +#. IndexFiles..GroupBox1..Delete..Caption +#: Property Editors/colnedit.dfm:196 +#: Editors/dsdesign.dfm:157 +#: Editors/fldlinks.dfm:123 +#: Editors/ixedit.dfm:43 +msgid "&Delete" +msgstr "&Löschen" + +#. CollectionEditor..ActionList1..DeleteCmd..Hint +#: Property Editors/colnedit.dfm:198 +msgid "Delete Selected" +msgstr "Auswahl löschen" + +#. CollectionEditor..ActionList1..MoveUpCmd..Caption +#: Property Editors/colnedit.dfm:205 +msgid "Move &Up" +msgstr "Nach &oben" + +#. CollectionEditor..ActionList1..MoveUpCmd..Hint +#: Property Editors/colnedit.dfm:207 +msgid "Move Selected Up" +msgstr "Auswahl nach oben verschieben" + +#. CollectionEditor..ActionList1..MoveDownCmd..Caption +#: Property Editors/colnedit.dfm:214 +msgid "Move Dow&n" +msgstr "Nach &unten" + +#. CollectionEditor..ActionList1..MoveDownCmd..Hint +#: Property Editors/colnedit.dfm:216 +msgid "Move Selected Down" +msgstr "Auswahl nach unten verschieben" + +#. CollectionEditor..ActionList1..SelectAllCmd..Caption +#. UpdateSQLEditForm..FieldListPopup..miSelectAll..Caption +#: Property Editors/colnedit.dfm:223 +msgid "&Select All" +msgstr "Alles &markieren" + +#. DBEditForm..GroupBox1..Caption +#: Property Editors/dbedit.dfm:18 +msgid " Database " +msgstr " Datenbank " + +#. DBEditForm..GroupBox1..Label1..Caption +#: Property Editors/dbedit.dfm:25 +msgid "&Alias name:" +msgstr "Alia&sname:" + +#. DBEditForm..GroupBox1..Label2..Caption +#: Property Editors/dbedit.dfm:33 +msgid "&Driver name:" +msgstr "&Treiber-Name:" + +#. DBEditForm..GroupBox1..Label3..Caption +#: Property Editors/dbedit.dfm:41 +msgid "&Parameter overrides:" +msgstr "&Parameter überschreibt:" + +#. DBEditForm..GroupBox1..Label4..Caption +#. DefineField..FieldGroup..FieldNameLabel..Caption +#: Property Editors/dbedit.dfm:49 +msgid "&Name:" +msgstr "&Name:" + +#. DBEditForm..GroupBox1..DefaultsButton..Caption +#: Property Editors/dbedit.dfm:90 +msgid "D&efaults" +msgstr "&Vorgaben" + +#. DBEditForm..GroupBox1..ClearButton..Caption +#. LinkFields..ClearButton..Caption +#. IndexFiles..GroupBox1..Clear..Caption +#. PictureEditorDlg..GroupBox1..Clear..Caption +#: Property Editors/dbedit.dfm:99 +#: Editors/ixedit.dfm:53 +#: Editors/picedit.dfm:94 +msgid "&Clear" +msgstr "Ent&fernen" + +#. DBEditForm..GroupBox3..Caption +#: Property Editors/dbedit.dfm:116 +msgid " Options " +msgstr " Optionen " + +#. DBEditForm..GroupBox3..LoginPrompt..Caption +#: Property Editors/dbedit.dfm:123 +msgid "&Login prompt" +msgstr "L&ogin-Abfrage" + +#. DBEditForm..GroupBox3..KeepConnection..Caption +#: Property Editors/dbedit.dfm:131 +msgid "&Keep inactive connection" +msgstr "&Inaktive Verbindung halten" + +#. InputReqDialog..Caption +#: Property Editors/dbinpreq.dfm:6 +msgid "Input Requested" +msgstr "Eingabeaufforderung" + +#. InputReqDialog..OKButton..Caption +#. LoginDialog..OKButton..Caption +#. DataBindForm..OkBtn..Caption +#. SQLEditForm..ButtonPanel..OkButton..Caption +#. StrEditDlg..OKButton..Caption +#. UpdateSQLEditForm..OkButton..Caption +#: Property Editors/dbinpreq.dfm:18 +#: Editors/dboleedt.dfm:109 +#: Editors/sqledit.dfm:94 +#: Editors/stredit.dfm:55 +#: Editors/updsqled.dfm:20 +msgid "&OK" +msgstr "&OK" + +#. InputReqDialog..NoPromptAgain..Caption +#: Property Editors/dbinpreq.dfm:48 +msgid "Don't Prompt Again" +msgstr "Meldung nicht mehr anzeigen" + +#. LoginDialog..Caption +#: Property Editors/dblogdlg.dfm:6 +msgid "Database Login" +msgstr "Datenbank-Login" + +#. LoginDialog..Panel..Label3..Caption +#: Property Editors/dblogdlg.dfm:47 +msgid "Database:" +msgstr "Datenbank:" + +#. LoginDialog..Panel..Panel1..Label1..Caption +#: Property Editors/dblogdlg.dfm:75 +msgid "&User Name:" +msgstr "&Benutzername:" + +#. LoginDialog..Panel..Panel1..Label2..Caption +#: Property Editors/dblogdlg.dfm:83 +msgid "&Password:" +msgstr "&Passwort:" + +#. LoginDialog..Panel..Panel1..Password..PasswordChar +#: Property Editors/dblogdlg.dfm:100 +msgid "*" +msgstr "*" + +#. DataBindForm..Caption +#: Property Editors/dboleedt.dfm:6 +msgid "ActiveX Control Data Bindings Editor" +msgstr "Editor für ActiveX-Datenbindung" + +#. DataBindForm..Panel1..Label1..Caption +#: Property Editors/dboleedt.dfm:29 +msgid "&Property Name:" +msgstr "Name der &Eigenschaft:" + +#. DataBindForm..Panel1..Label2..Caption +#: Property Editors/dboleedt.dfm:37 +msgid "&Field Name:" +msgstr "&Feldname:" + +#. DataBindForm..Panel1..Label3..Caption +#: Property Editors/dboleedt.dfm:45 +msgid "Bo&und Properties to Fields:" +msgstr "&Bindung von Eigenschaften an Feld:" + +#. DataBindForm..Panel1..BindBtn..Caption +#: Property Editors/dboleedt.dfm:73 +msgid "<- &Bind ->" +msgstr "<- B&indung ->" + +#. DataBindForm..Panel1..ClearBtn..Caption +#: Property Editors/dboleedt.dfm:99 +msgid "C&lear" +msgstr "E&ntfernen" + +#. AddFields..Caption +#: Property Editors/dsadd.dfm:6 +msgid "Add Fields" +msgstr "Felder hinzufügen" + +#. AddFields..GroupBox1..Caption +#: Property Editors/dsadd.dfm:46 +msgid "Available fields" +msgstr "Verfügbare Felder" + +#. AssociateAttributes..Caption +#: Property Editors/dsattra.dfm:5 +msgid "Associate attributes" +msgstr "Attribute verknüpfen" + +#. AssociateAttributes..GroupBox1..Caption +#: Property Editors/dsattra.dfm:51 +msgid "Attribute set name" +msgstr "Name der Attributmenge" + +#. SaveAttributesAs..Caption +#: Property Editors/dsattrs.dfm:5 +msgid "Save %s attributes as" +msgstr "%s-Attribute unter anderem Namen speichern" + +#. SaveAttributesAs..Label1..Caption +#: Property Editors/dsattrs.dfm:25 +msgid "&Attribute set name:" +msgstr "Name der &Attributmenge:" + +#. SaveAttributesAs..Label2..Caption +#: Property Editors/dsattrs.dfm:33 +msgid "&Based on:" +msgstr "&Basierend auf:" + +#. DefineField..Caption +#: Property Editors/dsdefine.dfm:5 +msgid "New Field" +msgstr "Neues Feld" + +#. DefineField..LookupGroup..Caption +#: Property Editors/dsdefine.dfm:18 +msgid "Lookup definition" +msgstr "Nachschlage-Definition" + +#. DefineField..LookupGroup..DatasetLabel..Caption +#: Property Editors/dsdefine.dfm:25 +msgid "D&ataset:" +msgstr "Daten&menge:" + +#. DefineField..LookupGroup..KeyFieldsLabel..Caption +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label3..Caption +#: Property Editors/dsdefine.dfm:34 +msgid "&Key Fields:" +msgstr "&Schlüsselfelder:" + +#. DefineField..LookupGroup..LookupKeysLabel..Caption +#: Property Editors/dsdefine.dfm:43 +msgid "Look&up Keys:" +msgstr "S&chlüssel:" + +#. DefineField..LookupGroup..ResultFieldLabel..Caption +#: Property Editors/dsdefine.dfm:52 +msgid "&Result Field:" +msgstr "E&rgebnisfeld:" + +#. DefineField..FieldGroup..Caption +#: Property Editors/dsdefine.dfm:133 +msgid "Field properties" +msgstr "Feldeigenschaften" + +#. DefineField..FieldGroup..ComponentNameLabel..Caption +#: Property Editors/dsdefine.dfm:140 +msgid "C&omponent:" +msgstr "K&omponente:" + +#. DefineField..FieldGroup..FieldTypeLabel..Caption +#: Property Editors/dsdefine.dfm:156 +msgid "&Type:" +msgstr "&Typ:" + +#. DefineField..FieldGroup..SizeEditLabel..Caption +#: Property Editors/dsdefine.dfm:164 +msgid "&Size:" +msgstr "&Größe:" + +#. DefineField..FieldKind..Caption +#: Property Editors/dsdefine.dfm:206 +msgid "Field type" +msgstr "Feldtyp" + +#. DefineField..FieldKind....Items.Strings +#: Property Editors/dsdefine.dfm:213 +msgid "" +"&Data\n" +"&Calculated\n" +"&Lookup\n" +msgstr "" +"&Daten\n" +"&Berechnung\n" +"&Lookup\n" + +#. FieldsEditor..FieldListBox..Hint +#: Property Editors/dsdesign.dfm:81 +msgid "Fields" +msgstr "Felder" + +#. FieldsEditor..AggListBox..Hint +#: Property Editors/dsdesign.dfm:99 +msgid "Aggregates" +msgstr "Aggregatfunktionen" + +#. FieldsEditor..LocalMenu..AddItem..Caption +#: Property Editors/dsdesign.dfm:119 +msgid "&Add fields..." +msgstr "&Felder hinzufügen..." + +#. FieldsEditor..LocalMenu..NewItem..Caption +#: Property Editors/dsdesign.dfm:125 +msgid "&New field..." +msgstr "&Neues Feld..." + +#. FieldsEditor..LocalMenu..Addallfields1..Caption +#: Property Editors/dsdesign.dfm:131 +msgid "Add all &fields" +msgstr "Alle Fel&der hinzufügen..." + +#. FieldsEditor..LocalMenu..CutItem..Caption +#: Property Editors/dsdesign.dfm:139 +msgid "Cu&t" +msgstr "&Ausschneiden" + +#. FieldsEditor..LocalMenu..CopyItem..Caption +#: Property Editors/dsdesign.dfm:145 +msgid "&Copy" +msgstr "&Kopieren" + +#. FieldsEditor..LocalMenu..PasteItem..Caption +#: Property Editors/dsdesign.dfm:151 +msgid "&Paste" +msgstr "&Einfügen" + +#. FieldsEditor..LocalMenu..SelectAllItem..Caption +#: Property Editors/dsdesign.dfm:163 +msgid "Se&lect all" +msgstr "Alles mar&kieren" + +#. LinkFields..Caption +#: Property Editors/fldlinks.dfm:6 +msgid "Field Link Designer" +msgstr "Feldverbindungs-Designer" + +#. LinkFields..Label30..Caption +#: Property Editors/fldlinks.dfm:35 +msgid "D&etail Fields" +msgstr "D&etailfelder" + +#. LinkFields..Label31..Caption +#: Property Editors/fldlinks.dfm:44 +msgid "&Master Fields" +msgstr "H&auptfelder" + +#. LinkFields..IndexLabel..Caption +#: Property Editors/fldlinks.dfm:53 +msgid "A&vailable Indexes" +msgstr "Verfügbare &Indizes" + +#. LinkFields..Label2..Caption +#: Property Editors/fldlinks.dfm:61 +msgid "&Joined Fields" +msgstr "Ver&knüpfte Felder" + +#. IndexFiles..Caption +#. IndexFiles..GroupBox1..Caption +#: Property Editors/ixedit.dfm:5 +msgid "Index Files" +msgstr "Indexdateien" + +#. IndexFiles..GroupBox1..Add..Caption +#: Property Editors/ixedit.dfm:34 +msgid "&Add..." +msgstr "Hin&zufügen..." + +#. IndexFiles..OpenDialog....OnClick +#: Property Editors/ixedit.dfm:92 +msgid "dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" +msgstr "dBASE Mehrfachindex (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" + +#. PictureEditorDlg..Caption +#: Property Editors/picedit.dfm:6 +msgid "Picture Editor" +msgstr "Bild-Editor" + +#. PictureEditorDlg..GroupBox1..Load..Caption +#. StrEditDlg..StringEditorMenu..LoadItem..Caption +#: Property Editors/picedit.dfm:76 +msgid "&Load..." +msgstr "&Laden..." + +#. PictureEditorDlg..GroupBox1..Save..Caption +#. StrEditDlg..StringEditorMenu..SaveItem..Caption +#: Property Editors/picedit.dfm:85 +msgid "&Save..." +msgstr "&Speichern..." + +#. PictureEditorDlg..OpenDialog....OnClick +#. PictureEditorDlg..SaveDialog....Top +#: Property Editors/picedit.dfm:104 +msgid "All (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf\n" +msgstr "Alle (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Erweiterte Metadateien (*.emf)|*.emf|Metadateien (*.wmf)|*.wmf\n" + +#. SQLEditForm..Caption +#: Property Editors/sqledit.dfm:5 +msgid "CommandText Editor" +msgstr "Anweisungstext-Editor" + +#. SQLEditForm..TopPanel..TableListLabel..Caption +#: Property Editors/sqledit.dfm:52 +msgid "&Tables:" +msgstr "&Tabellen:" + +#. SQLEditForm..TopPanel..SQLLabel..Caption +#: Property Editors/sqledit.dfm:60 +msgid "&SQL:" +msgstr "&SQL:" + +#. SQLEditForm..MetaInfoPanel..TableListPanel..AddTableButton..Caption +#: Property Editors/sqledit.dfm:165 +msgid "Add T&able to SQL" +msgstr "T&abelle zu SQL hinzufügen" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..FieldListLabel..Caption +#: Property Editors/sqledit.dfm:183 +msgid "&Fields:" +msgstr "&Felder:" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..AddFieldButton..Caption +#: Property Editors/sqledit.dfm:203 +msgid "Add F&ield to SQL" +msgstr "F&eld zu SQL hinzufügen" + +#. StrEditDlg..Caption +#: Property Editors/stredit.dfm:5 +msgid "String List editor" +msgstr "String-Listen-Editor" + +#. StrEditDlg..LineCount..Caption +#: Property Editors/stredit.dfm:29 +msgid "0 lines" +msgstr "0 Linien" + +#. StrEditDlg..CodeWndBtn..Caption +#. StrEditDlg..StringEditorMenu..CodeEditorItem..Caption +#: Property Editors/stredit.dfm:36 +msgid "&Code Editor..." +msgstr "&Quelltext-Editor..." + +#. StrEditDlg..OpenDialog..DefaultExt +#: Property Editors/stredit.dfm:84 +msgid "TXT" +msgstr "TXT" + +#. StrEditDlg..OpenDialog....DefaultExt +#. StrEditDlg..SaveDialog....Left +#: Property Editors/stredit.dfm:88 +msgid "Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|Batch files (*.BAT)|*.BAT|All files (*.*)|*.*\n" +msgstr "Textdateien (*.TXT)|*.TXT|Konfigurationsdateien (*.SYS;*.INI)|*.SYS;*.INI|Batchdateien (*.BAT)|*.BAT|Alle Dateien (*.*)|*.*\n" + +#. StrEditDlg..OpenDialog..Title +#: Property Editors/stredit.dfm:89 +msgid "Load string list" +msgstr "String-Liste laden" + +#. StrEditDlg..SaveDialog..Title +#: Property Editors/stredit.dfm:97 +msgid "Save string list" +msgstr "String-Liste speichern" + +#. UpdateSQLEditForm..PageControl..FieldsPage..Caption +#: Property Editors/updsqled.dfm:54 +msgid "Options" +msgstr "Optionen" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Caption +#: Property Editors/updsqled.dfm:60 +msgid " SQL Generation " +msgstr "SQL Generierung" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label1..Caption +#: Property Editors/updsqled.dfm:67 +msgid "Table &Name:" +msgstr "Tabellen&name:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label4..Caption +#: Property Editors/updsqled.dfm:83 +msgid "Update &Fields:" +msgstr "Update &Felder:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GenerateButton..Caption +#: Property Editors/updsqled.dfm:123 +msgid "&Generate SQL" +msgstr "SQL &generieren" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..PrimaryKeyButton..Caption +#: Property Editors/updsqled.dfm:132 +msgid "Select &Primary Keys" +msgstr "Hau&ptschlüsseln auswählen" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..DefaultButton..Caption +#: Property Editors/updsqled.dfm:141 +msgid "&Dataset Defaults" +msgstr "&Dataset Voreinstellungen" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..QuoteFields..Caption +#: Property Editors/updsqled.dfm:151 +msgid "&Quote Field Names" +msgstr "&Feldname in Hochkoma setzen:" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GetTableFieldsButton..Caption +#: Property Editors/updsqled.dfm:160 +msgid "Get &Table Fields" +msgstr "&Tabellenfelder holen" + +#. UpdateSQLEditForm..PageControl..SQLPage..Caption +#: Property Editors/updsqled.dfm:167 +msgid "SQL" +msgstr "SQL" + +#. UpdateSQLEditForm..PageControl..SQLPage..Label2..Caption +#: Property Editors/updsqled.dfm:173 +msgid "S&QL Text:" +msgstr "S&QL Text:" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType..Caption +#: Property Editors/updsqled.dfm:190 +msgid "Statement Type" +msgstr "Angabentyp" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType....Items.Strings +#: Property Editors/updsqled.dfm:197 +msgid "" +"&Modify\n" +"&Insert\n" +"&Delete\n" +msgstr "" +"&Modifizieren\n" +"&Einfügen\n" +"&Löschen\n" + +#. UpdateSQLEditForm..FieldListPopup..miClearAll..Caption +#: Property Editors/updsqled.dfm:214 +msgid "&Clear All" +msgstr "Alles Entfernen" + +#. HTTPServer......Name +#: Vcl/httpintr.dfm:6 +msgid "Interpreter" +msgstr "Interpreter" + +#. SocketForm..Caption +#: Vcl/scktmain.dfm:6 +msgid "Borland Socket Server" +msgstr "Borland Socket-Server" + +#. SocketForm..Pages..PropPage..PortGroup..Caption +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#. SocketForm..Panel1..HeaderControl1......Text +#: Vcl/scktmain.dfm:38 +msgid "Port" +msgstr "Port" + +#. SocketForm..Pages..PropPage..PortGroup..Label1..Caption +#: Vcl/scktmain.dfm:46 +msgid "&Listen on Port:" +msgstr "P&ort überwachen:" + +#. SocketForm..Pages..PropPage..PortGroup..PortDesc....AutoSize +#: Vcl/scktmain.dfm:60 +msgid "Many values of Port are associated by convention with a particular service such as ftp or http. Port is the ID of the connection on which the server listens for client requests. \n" +msgstr "Viele Werte von Port sind mit bestimmten Diensten wie ftp oder http assoziiert. Port ist die ID der Verbindung, auf der der Server auf Client-Anfragen wartet. \n" + +#. SocketForm..Pages..PropPage..ThreadGroup..Caption +#: Vcl/scktmain.dfm:92 +msgid "Thread Caching" +msgstr "Thread-Pufferung" + +#. SocketForm..Pages..PropPage..ThreadGroup..Label4..Caption +#: Vcl/scktmain.dfm:100 +msgid "&Thread Cache Size:" +msgstr "Größe des &Thread-Puffers:" + +#. SocketForm..Pages..PropPage..ThreadGroup..ThreadDesc....AutoSize +#: Vcl/scktmain.dfm:113 +msgid "Thread Cache Size is the maximum number of threads that can be reused for new client connections.\n" +msgstr "Thread Cache Size ist die maximale Anzahl der Threads, die für neue Cleint-Verbindungen wiederbenutzt werden können.\n" + +#. SocketForm..Pages..PropPage..InterceptGroup..Caption +#: Vcl/scktmain.dfm:145 +msgid "Intercept GUID" +msgstr "Abfang-GUID" + +#. SocketForm..Pages..PropPage..InterceptGroup..Label5..Caption +#: Vcl/scktmain.dfm:152 +msgid "&GUID:" +msgstr "&GUID:" + +#. SocketForm..Pages..PropPage..InterceptGroup..GUIDDesc....AutoSize +#: Vcl/scktmain.dfm:164 +msgid "Intercept GUID is the GUID for a data interceptor COM object. See help for the TSocketConnection for details.\n" +msgstr "Intercept GUID ist die GUID für ein Data Interceptor COM-Objekt. Für Details siehe Hilfe von TSocketConnection.\n" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Caption +#: Vcl/scktmain.dfm:180 +msgid "Timeout" +msgstr "Zeitüberschreitung" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Label7..Caption +#: Vcl/scktmain.dfm:188 +msgid "&Inactive Timeout:" +msgstr "&Inaktivitäts-Timeout:" + +#. SocketForm..Pages..PropPage..TimeoutGroup..TimeoutDesc....AutoSize +#: Vcl/scktmain.dfm:201 +msgid "Inactive Timeout specifes the number of minutes a client can be inactive before being disconnected. (0 indicates infinite)\n" +msgstr "Inaktivitäts-Timeout gibt die Minuten an, bevor die Verbindung zu einem nicht aktiver Client getrennt wird. (0 bedeutet kein Timeout)\n" + +#. SocketForm..Pages..StatPage..Caption +#: Vcl/scktmain.dfm:239 +msgid "Users" +msgstr "Benutzer" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:252 +msgid "IP Address" +msgstr "IP-Adresse" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:256 +msgid "Host" +msgstr "Host" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:260 +msgid "Last Activity" +msgstr "Letzte Aktivität" + +#. SocketForm..PopupMenu..miProperties..Caption +#: Vcl/scktmain.dfm:327 +msgid "&Properties" +msgstr "&Eigenschaften" + +#. SocketForm..MainMenu1..miPorts..Caption +#: Vcl/scktmain.dfm:343 +msgid "&Ports" +msgstr "&Ports" + +#. SocketForm..MainMenu1..miPorts..miExit..Caption +#: Vcl/scktmain.dfm:355 +msgid "&Exit" +msgstr "&Beenden" + +#. SocketForm..MainMenu1..Connections1..Caption +#: Vcl/scktmain.dfm:360 +msgid "&Connections" +msgstr "V&erbindungen" + +#. SocketForm..ActionList1..ApplyAction..Caption +#: Vcl/scktmain.dfm:379 +msgid "&Apply" +msgstr "Ü&bernehmen" + +#. SocketForm..ActionList1..DisconnectAction..Caption +#: Vcl/scktmain.dfm:384 +msgid "&Disconnect" +msgstr "&Verbindung trennen" + +#. SocketForm..ActionList1..ShowHostAction..Caption +#: Vcl/scktmain.dfm:389 +msgid "&Show Host Name" +msgstr "Zeige Ho&stname" + +#. SocketForm..ActionList1..RemovePortAction..Caption +#: Vcl/scktmain.dfm:394 +msgid "&Remove" +msgstr "Ent&fernen" + +#. SocketForm..ActionList1..RegisteredAction..Caption +#: Vcl/scktmain.dfm:399 +msgid "&Registered Objects Only" +msgstr "&Nur registrierte Objekte" + +#~ msgid " &Images " +#~ msgstr " B&ilder " +#~ msgid " &Selected Image " +#~ msgstr " Ausge&wählte Grafik " +#~ msgid " Log S&ize " +#~ msgstr " &Protokollgröße " +#~ msgid " Value" +#~ msgstr " Wert" +#~ msgid " any known drive" +#~ msgstr " Alle bekannten Laufwerke" +#~ msgid " not specified" +#~ msgstr " nicht angegeben" +#~ msgid "" +#~ "\"%s\"\n" +#~ "File not found." +#~ msgstr "" +#~ "\"%s\"\n" +#~ "Datei nicht gefunden." +#~ msgid "" +#~ "\"%s\"\n" +#~ "File not found.\n" +#~ "Please verify the correct filename was given." +#~ msgstr "" +#~ "\"%s\"\n" +#~ "Datei nicht gefunden.\n" +#~ "Überprüfen Sie, ob der\t korrekte Dateiname angegeben wurde." +#~ msgid "" +#~ "\"%s\"\n" +#~ "Path not found.\n" +#~ "Please verify the correct path was given." +#~ msgstr "" +#~ "%s\n" +#~ "Pfad nicht gefunden.\n" +#~ "Überprüfen Sie, ob der korrektePfad angegeben wurde." +#~ msgid "\"%s\" Command not implemented." +#~ msgstr "\"%s\" Anweisung nicht implementiert." +#~ msgid "\"%s\" DOMImplementation already registered" +#~ msgstr "DOM-Implementierung \"%s\" bereits registriert" +#~ msgid "" +#~ "\"%s\" already exists.\n" +#~ "Do you want to replace it?" +#~ msgstr "" +#~ "%s existiert bereits.\n" +#~ "Soll es überschrieben werden?" +#~ msgid "\"%s\" created." +#~ msgstr "\"%s\" erzeugt." +#~ msgid "\"%s\" is is working directory." +#~ msgstr "\"%s\" ist Arbeitsverzeichnis." +#~ msgid "\"%s\" is not a subdirectory of \"%s\"" +#~ msgstr "\"%s\" ist kein Unterverzeichnis von \"%s\"" +#~ msgid "%0:s: Action %1:s not found in associated Adapter" +#~ msgstr "%0:s: Aktion %1:s im zugeordneten Adapter nicht gefunden" +#~ msgid "%0:s: Dataset %1:s not active" +#~ msgstr "%0:s: Datenmenge %1:s ist nicht aktiv" +#~ msgid "%0:s: Dataset %1:s unknown keyfields" +#~ msgstr "%0:s: Datenmenge %1:s unbekannte Schlüsselfelder" +#~ msgid "%0:s: Field %1:s not found in associated Adapter" +#~ msgstr "%0:s: Feld %1:s im zugeordneten Adapter nicht gefunden" +#~ msgid "%0:s: ValueField property value is blank" +#~ msgstr "%0:s: Eigenschaftswert von ValueField ist leer" +#~ msgid "%d MB" +#~ msgstr "%d MB" +#~ msgid "%d: Circular links are not allowed" +#~ msgstr "%d: Zirkulärverweise sind nicht gestattet" +#~ msgid "%f Julian cannot be represented as a DateTime" +#~ msgstr "" +#~ "%f Julianischer Wert kann nicht als Datum/Uhrzeitwert dargestellt werden" +#~ msgid "%s" +#~ msgstr "%s" +#~ msgid "%s %s Error: (%d)%s" +#~ msgstr "%s %s Fehler (%d)%s" +#~ msgid "%s - %s" +#~ msgstr "%s - %s" +#~ msgid "%s - PortTypes:" +#~ msgstr "%s - PortTypen:" +#~ msgid "%s ActionManager property has not been assigned" +#~ msgstr "%s ActionManager-Eigenschaft wurde nichts zugewiesen" +#~ msgid "%s Address Error" +#~ msgstr "%s Adress-Fehler" +#~ msgid "%s Address Okay" +#~ msgstr "%s Adresse OK" +#~ msgid "%s Command successful." +#~ msgstr "%s Anweisung erfolgreich." +#~ msgid "%s Non-visual component for 32-bit Delphi." +#~ msgstr "%s Nichtvisuelle Komponente für 32-Bit Delphi." +#~ msgid "%s [%s%s]" +#~ msgstr "%s [%s%s]" +#~ msgid "%s cannot be set on a ref item" +#~ msgstr "%s darf für ein Verweiselement nicht gesetzt werden" +#~ msgid "%s component requires Client to function properly" +#~ msgstr "Komponente %s setzt voraus, dass der Client richtig funktioniert." +#~ msgid "%s component requires Server to function properly" +#~ msgstr "Komponente %s setzt voraus, dass der Server richtig funktioniert." +#~ msgid "%s could not be loaded." +#~ msgstr "%s konnte nicht geladen werden." +#~ msgid "%s directory structure." +#~ msgstr "%s Verzeichnisstruktur." +#~ msgid "%s does not allow hiding" +#~ msgstr "%s kann nicht verborgen werden" +#~ msgid "%s does not allow multiple files" +#~ msgstr "Mehrere Dateien bei %s nicht zulässig" +#~ msgid "%s does not allow multiple values" +#~ msgstr "Mehrere Werte bei %s nicht zulässig" +#~ msgid "%s does not support file upload" +#~ msgstr "%s unterstützt den Datei-Upload nicht" +#~ msgid "%s has a factor of zero" +#~ msgstr "%s hat den Faktor Null" +#~ msgid "%s is already in the StatusBar" +#~ msgstr "%s befindet sich bereits in der Statuszeile" +#~ msgid "%s is corrupt." +#~ msgstr "%s ist beschädigt." +#~ msgid "%s is not a Gopher+ server" +#~ msgstr "%s ist kein Gopher+-Server" +#~ msgid "%s is not a valid BCD value" +#~ msgstr "%s ist kein gültiger BCD-Wert" +#~ msgid "%s is not a valid hex string" +#~ msgstr "%s ist kein gültiger Hex-String" +#~ msgid "%s is not a valid service." +#~ msgstr "%s ist kein gültiger Service." +#~ msgid "" +#~ "%s is not a valid value for field '%s'. The allowed range is %s to %s" +#~ msgstr "" +#~ "%s ist kein gültiger Wert für Feld '%s'. Der zulässige Bereich ist %s bis " +#~ "%s" +#~ msgid "%s not in a class registration group" +#~ msgstr "%s befindet sich nicht in einer Gruppe für Klassenregistrierungen" +#~ msgid "%s requires a file" +#~ msgstr "Für %s ist eine Datei erforderlich" +#~ msgid "%s%s%s %s" +#~ msgstr "%s%s%s %s" +#~ msgid "%s, Default" +#~ msgstr "%s, Standard" +#~ msgid "%s.Seek not implemented" +#~ msgstr "%s.Seek nicht implementiert" +#~ msgid "%s: Action name is blank" +#~ msgstr "%s: Aktionsname fehlt" +#~ msgid "%s: Adapter property is nil" +#~ msgstr "%s: Adaptereigenschaft ist nil" +#~ msgid "%s: DataSet property is nil" +#~ msgstr "%s: Eigenschaft DataSet ist nil" +#~ msgid "%s: DisplayComponent property is nil" +#~ msgstr "%s: Eigenschaft DisplayComponent ist nil" +#~ msgid "%s: Fieldname is blank" +#~ msgstr "%s: Feldname fehlt" +#~ msgid "&About..." +#~ msgstr "&Info..." +#~ msgid "&Activate at Startup" +#~ msgstr "Bei Start &aktivieren" +#~ msgid "&Active" +#~ msgstr "&Aktiv" +#~ msgid "&Add or Remove Buttons" +#~ msgstr "&Schaltflächen hinzufügen oder entfernen" +#~ msgid "&Allow XML Packets" +#~ msgstr "Erl&aube XML-Pakete" +#~ msgid "&Apply Event" +#~ msgstr "Ereignis &anwenden" +#~ msgid "&Arrange" +#~ msgstr "An&ordnen" +#~ msgid "&Back" +#~ msgstr "&Zurück" +#~ msgid "&Bindings" +#~ msgstr "&Bindungen" +#~ msgid "&Bold" +#~ msgstr "Fe&tt" +#~ msgid "&Browse" +#~ msgstr "&Durchsuchen..." +#~ msgid "&Browse URL" +#~ msgstr "&URL durchsuchen" +#~ msgid "&Browser:" +#~ msgstr "&Browser:" +#~ msgid "&Bullets" +#~ msgstr "&Aufzählungszeichen" +#~ msgid "&Caption Options" +#~ msgstr "Ü&berschriftoptionen" +#~ msgid "&Caption:" +#~ msgstr "&Titel:" +#~ msgid "&Cascade" +#~ msgstr "Ü&berlappend" +#~ msgid "&Center" +#~ msgstr "&Zentriert" +#~ msgid "&Connection" +#~ msgstr "V&erbindung" +#~ msgid "&Contents" +#~ msgstr "I&nhalt" +#~ msgid "&Copy Selection" +#~ msgstr "Auswahl &kopieren" +#~ msgid "&Customize" +#~ msgstr "A&npassen" +#~ msgid "&Database:" +#~ msgstr "Datenban&k:" +#~ msgid "&Dataset Editor..." +#~ msgstr "&Dataset-Editor..." +#~ msgid "&Default URL:" +#~ msgstr "Standard-&URL:" +#~ msgid "&Delete Selection" +#~ msgstr "Auswahl &entfernen" +#~ msgid "&Delete when max exceeded:" +#~ msgstr "Bei Überschreiten des &Maximums löschen:" +#~ msgid "&Detail" +#~ msgstr "&Details" +#~ msgid "&Details..." +#~ msgstr "&Details..." +#~ msgid "&Down" +#~ msgstr "A&bwärts" +#~ msgid "&Download URL" +#~ msgstr "Von &URL herunterladen" +#~ msgid "&Edit CommandText" +#~ msgstr "Anweisungstext &bearbeiten" +#~ msgid "&Edit Connection Properties" +#~ msgstr "&Verbindungseigenschaften bearbeiten" +#~ msgid "&Field" +#~ msgstr "&Feld" +#~ msgid "&Fill Color:" +#~ msgstr "Füllf&arbe:" +#~ msgid "&Find Next" +#~ msgstr "&Weitersuchen" +#~ msgid "&Find..." +#~ msgstr "Su&chen..." +#~ msgid "&Finish" +#~ msgstr "&Fertig stellen" +#~ msgid "&Forward" +#~ msgstr "&Weiter" +#~ msgid "&Help on Help" +#~ msgstr "&Verwendung der Hilfe" +#~ msgid "&IP Address" +#~ msgstr "&IP-Adresse" +#~ msgid "&Italic" +#~ msgstr "&Kursiv" +#~ msgid "&Items" +#~ msgstr "&Einträge" +#~ msgid "&Large icons" +#~ msgstr "&Große Symbole" +#~ msgid "&List" +#~ msgstr "&Liste" +#~ msgid "&Local" +#~ msgstr "&Lokal" +#~ msgid "&Log" +#~ msgstr "Pr&otokoll" +#~ msgid "&Log To List" +#~ msgstr "&Log in Liste" +#~ msgid "&Log Traffic" +#~ msgstr "&Log des Verkehrs" +#~ msgid "&Look in:" +#~ msgstr "&Suchen in:" +#~ msgid "&Menu animations:" +#~ msgstr "&Menüanimationen:" +#~ msgid "&Minimize All" +#~ msgstr "&Alle verkleinern" +#~ msgid "&Move Selection" +#~ msgstr "Auswahl &verlagern" +#~ msgid "&New Item" +#~ msgstr "&Neuer Eintrag" +#~ msgid "&New Message Part..." +#~ msgstr "&Neuer Botschaftsteil..." +#~ msgid "&New Node" +#~ msgstr "&Neuer Knoten" +#~ msgid "&Next" +#~ msgstr "Tab" +#~ msgid "&Open" +#~ msgstr "Ö&ffnen" +#~ msgid "&Open Picture..." +#~ msgstr "&Bild öffnen..." +#~ msgid "&Open..." +#~ msgstr "Ö&ffnen..." +#~ msgid "&Options..." +#~ msgstr "&Optionen..." +#~ msgid "&Port" +#~ msgstr "&Port" +#~ msgid "&Port:" +#~ msgstr "&Port:" +#~ msgid "&Previous" +#~ msgstr "&Zurück" +#~ msgid "&Print..." +#~ msgstr "D&rucken..." +#~ msgid "&Protocol:" +#~ msgstr "&Protokoll:" +#~ msgid "&Reload" +#~ msgstr "Neu &laden" +#~ msgid "&Remote" +#~ msgstr "E&xtern" +#~ msgid "&Rename" +#~ msgstr "U&mbenennen" +#~ msgid "&Replace" +#~ msgstr "Erset&zen" +#~ msgid "&Reset" +#~ msgstr "&Zurücksetzen" +#~ msgid "&Reset..." +#~ msgstr "Symbolleisten" +#~ msgid "&Run..." +#~ msgstr "&Ausführen..." +#~ msgid "&Save Picture..." +#~ msgstr "Bild &speichern..." +#~ msgid "&Search Path:" +#~ msgstr "&Suchpfad:" +#~ msgid "&Send Mail..." +#~ msgstr "Mail &senden..." +#~ msgid "&Server" +#~ msgstr "&Server:" +#~ msgid "&Server:" +#~ msgstr "&Server:" +#~ msgid "&Service Editor ..." +#~ msgstr "&Service-Editor..." +#~ msgid "&Show in Log" +#~ msgstr "I&n Protokoll anzeigen" +#~ msgid "&Small Icons" +#~ msgstr "&Kleine Symbole" +#~ msgid "&Start Server" +#~ msgstr "&Server starten" +#~ msgid "&State Index:" +#~ msgstr "Status-&Index:" +#~ msgid "&Strikeout" +#~ msgstr "Format" +#~ msgid "&Tile Vertically" +#~ msgstr "&Vertikal anordnen" +#~ msgid "&Toolbar Options" +#~ msgstr "Sy&mbolleistenoptionen" +#~ msgid "&Topic Search" +#~ msgstr "&Suche über Schlüsselwort" +#~ msgid "&Translate Post" +#~ msgstr "&POST übersetzen" +#~ msgid "&Translate Text" +#~ msgstr "&Text übersetzen" +#~ msgid "&Transparent Color:" +#~ msgstr "&Transparent:" +#~ msgid "&UDP Port:" +#~ msgstr "U&DP-Port:" +#~ msgid "&Underline" +#~ msgstr "&Unterstrichen" +#~ msgid "&Undo" +#~ msgstr "&Rückgängig" +#~ msgid "&Up" +#~ msgstr "A&ufwärts" +#~ msgid "&Up one directory" +#~ msgstr "Ein Verzeichnis nach &oben" +#~ msgid "&Web Page Editor..." +#~ msgstr "Editor für &Web-Seiten..." +#~ msgid "&Wrap Text" +#~ msgstr "Text &umbrechen" +#~ msgid "" +#~ "  Link to WS-Inspection document of " +#~ "Services here" +#~ msgstr "" +#~ "  Verknüpfung mit WS-Inspektionsdokument " +#~ "der Services hier" +#~ msgid "'%d.%d' is not a valid timestamp" +#~ msgstr "'%d.%d' ist kein gültiger Zeitstempel" +#~ msgid "'%g' is not a valid date and time" +#~ msgstr "'%g' kein gültiger Datums- und Zeitwet" +#~ msgid "'%s' is not a valid GUID value" +#~ msgstr "'%s' kein gültiger Wert für GUID" +#~ msgid "'%s' is not a valid boolean value" +#~ msgstr "'%s' ist kein gültiger boolescher Wert" +#~ msgid "'%s' is not a valid currency value" +#~ msgstr "'%s' ist kein gültiger Währungwert" +#~ msgid "(%d, %d) is not a valid DateDay pair" +#~ msgstr "(%d, %d) ist kein gültiger Wert für die Tagesangabe im Datum" +#~ msgid "(%d, %d, %d) is not a valid DateWeek triplet" +#~ msgstr "(%d, %d, %d) ist kein gültiger Wert für die Wochenangabe im Datum" +#~ msgid "(%d, %d, %d, %d) is not a valid DateMonthWeek quad" +#~ msgstr "" +#~ "(%d, %d, %d, %d) ist kein gültiger Wert für die Monats- und Wochenangabe " +#~ "im Datum" +#~ msgid "(%d, %d, %d, %d) is not a valid DayOfWeekInMonth quad" +#~ msgstr "" +#~ "(%d, %d, %d, %d) ist kein gültiger Wert für dieTages- und Monatsangabe im " +#~ "Datum" +#~ msgid "(ADT)" +#~ msgstr "(ADT)" +#~ msgid "(All Actions)" +#~ msgstr "(Alle Aktionen)" +#~ msgid "(Array)" +#~ msgstr "(Array)" +#~ msgid "(Binary)" +#~ msgstr "(Binär)" +#~ msgid "(Checkmark toggles visibility)" +#~ msgstr "(Häkchen schaltet Anzeige um)" +#~ msgid "(No Category)" +#~ msgstr "(Keine Kategorie)" +#~ msgid "(No Name)" +#~ msgstr "(Kein Name)" +#~ msgid "(Not available)" +#~ msgstr "(Nicht verfügbar)" +#~ msgid "(Null)" +#~ msgstr "(Null)" +#~ msgid "(Unassigned)" +#~ msgstr "(Nicht zugewiesen)" +#~ msgid "(none)" +#~ msgstr "(Leer)" +#~ msgid "-Err 501 MailB is not implemented" +#~ msgstr "-Err 501 MailB ist nicht implementiert" +#~ msgid "/Clean" +#~ msgstr "/Clean" +#~ msgid "/Details" +#~ msgstr "/Details" +#~ msgid "/List" +#~ msgstr "/List" +#~ msgid "1999 XML Schema Translator (.xsd <-> .xsd)" +#~ msgstr "1999 XML-Schema-Übersetzung (.xsd <-> .xsd)" +#~ msgid "3D Dark Shadow" +#~ msgstr "3D Dunkler Schatten" +#~ msgid "3D Light" +#~ msgstr "3D Hell" +#~ msgid "<#LIST>" +#~ msgstr "<#LIST>" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ msgstr "" +#~ msgid "\n" +#~ msgstr "\n" +#~ msgid "" +#~ "

Error Encountered

Interface %s not found

" +#~ msgstr "" +#~ "

Fehler aufgetreten

Interface %s wurde nicht " +#~ "gefunden

" +#~ msgid "" +#~ "

Forbidden (403)

Access Forbidden

" +#~ msgstr "" +#~ "

Verboten (403)

Zugang verboten

" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ msgstr "" +#~ msgid "" +#~ "Directory of %s

Directory of %" +#~ "0:s

\n" +#~ msgstr "" +#~ "Verzeichnis von %s

Verzeichnis " +#~ "von %0:s

\n" +#~ msgid "" +#~ "Unauthorized

UnauthorizedProper authorization is required for this area. Either your browser " +#~ "does not perform authorization, or your authorization has failed.\n" +#~ msgstr "" +#~ "Nicht autorisiert

Nicht " +#~ "autorisiert

Für diesen Bereich ist eine Anmeldung erforderlich. " +#~ "Entweder hat Ihr Browser keine Anmeldung durchgeführt oder Ihre Anmeldung " +#~ "ist mißlungen.\n" +#~ msgid "" +#~ "Directory browsing is forbidden

The " +#~ "requested URL is forbidden

HTTP status code: 403\n" +#~ msgstr "" +#~ "Das Durchsuchen von Verzeichnissen ist nicht gestattet</" +#~ "TITLE><BODY><H1>Der Zugriff auf die angeforderte URL ist nicht gestattet</" +#~ "H1><P>HTTP-Statuscode: 403</BODY></HTML>\n" +#~ msgid "" +#~ "<HTML><TITLE>Invalid HTTP request: Method not allowed for HTTP/1.0</" +#~ "TITLE><BODY><H1>Invalid HTTP request: Method not allowed for HTTP/1.0</" +#~ "H1><P>HTTP status code: 400</BODY></HTML>\n" +#~ msgstr "" +#~ "<HTML><TITLE>Ungültige HTTP-Anforderung: Methode für HTTP/1.0 nicht " +#~ "zulässig

Ungültige HTTP-Anforderung: Methode für " +#~ "HTTP/1.0 nicht zulässig

HTTP-Statuscode: 400\n" +#~ msgid "" +#~ "The requested URL is forbidden

The " +#~ "requested URL is forbidden

HTTP status code: 403\n" +#~ msgstr "" +#~ "Der Zugriff auf die angeforderte URL ist nicht gestattet</" +#~ "TITLE><BODY><H1>Der Zugriff auf die angeforderte URL ist nicht gestattet</" +#~ "H1><P>HTTP-Statuscode: 403</BODY></HTML>\n" +#~ msgid "<LF>" +#~ msgstr "<LF>" +#~ msgid "<LI><A HREF=\"%s\">%s</A> (%d bytes)\n" +#~ msgstr "<LI><A HREF=\"%s\">%s</A> (%d Bytes)\n" +#~ msgid "<LI>[ <A HREF=\"%s\">%s</A> ]\n" +#~ msgstr "<LI>[ <A HREF=\"%s\">%s</A> ]\n" +#~ msgid "<No Records>" +#~ msgstr "<Keine Datensätze>" +#~ msgid "" +#~ "<TITLE>Internal Server Error

Internal Server Error

HTTP status code: 500

HTTP error message: %s" +#~ msgstr "" +#~ "Interner Server-Fehler

Interner Server-Fehler

HTTP-Statuscode: 500

HTTP-Fehlermeldung: %s" +#~ msgid "" +#~ "The requested URL was not found

The requested URL " +#~ "was not found

HTTP status code: 404" +#~ msgstr "" +#~ "Die angeforderte URL wurde nicht gefunden

Die " +#~ "angeforderte URL wurde nicht gefunden

HTTP-Statuscode: 404" +#~ msgid "

    \n" +#~ msgstr "
      \n" +#~ msgid "" +#~ msgstr "" +#~ msgid "List>View List | View Details\n" +#~ msgstr "" +#~ "List>Zeige Lise | Zeige Details\n" +#~ msgid "%s > %s" +#~ msgstr "%s > %s" +#~ msgid "" +#~ "View List | Details\">View Details\n" +#~ msgstr "" +#~ "Zeige Liste | Details\">Zeige Details\n" +#~ msgid "" +#~ "

      Internal Application Error

      \n" +#~ "

      %0:s\n" +#~ "


      %1:s" +#~ msgstr "" +#~ "

      Interner Anwendungsfehler

      \n" +#~ "

      %0:s\n" +#~ "


      %1:s" +#~ msgid "" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "
      \n" +#~ "Error[%0:d]: \n" +#~ "%1:s\n" +#~ "\n" +#~ "
      \n" +#~ "Line: \n" +#~ "%2:d\n" +#~ "\n" +#~ "\n" +#~ "Position: \n" +#~ "%3:d\n" +#~ "\n" +#~ "
      \n" +#~ msgstr "" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "\n" +#~ "
      \n" +#~ "Fehler[%0:d]: \n" +#~ "%1:s\n" +#~ "\n" +#~ "
      \n" +#~ "Zeile: \n" +#~ "%2:d\n" +#~ "\n" +#~ "\n" +#~ "Position: \n" +#~ "%3:d\n" +#~ "\n" +#~ "
      \n" +#~ msgid "@ Outside address" +#~ msgstr "@ Outside-Adresse" +#~ msgid "A call to an OS function failed" +#~ msgstr "Ein Aufruf einer Betriebssystemfunktion ist fehlgeschlagen" +#~ msgid "" +#~ "A file with that name already exists. Please specify a different filename." +#~ msgstr "" +#~ "Eine Datei mit diesem Namen gibt es bereits. Geben Sie einen anderen " +#~ "Dateinamen an." +#~ msgid "A key with the name of \"%s\" already exists" +#~ msgstr "Schlüssel mit der Bezeichnung \"%s\" existiert bereits" +#~ msgid "A message has been received but the commication mode is unknown" +#~ msgstr "" +#~ "Es wurde eine Botschaft empfangen, aber der Kommunikationsmodus ist " +#~ "unbekannt" +#~ msgid "A script error occured. Do you want to debug?" +#~ msgstr "Es ist ein Script-Fehler aufgetreten. Möchten Sie ihn suchen?" +#~ msgid "A style named %s has already been registered" +#~ msgstr "Ein Attribut namens %s wurde bereits registriert" +#~ msgid "A transaction is already active" +#~ msgstr "Es ist bereits eine Transaktion aktiv" +#~ msgid "A&ctions:" +#~ msgstr "&Aktionen:" +#~ msgid "A&pply" +#~ msgstr "Ü&bernehmen" +#~ msgid "About" +#~ msgstr "Info" +#~ msgid "About Internet &Direct (Indy) %s..." +#~ msgstr "Info über Internet &Direct (Indy) %s..." +#~ msgid "About Web App Debugger" +#~ msgstr "Info über den Debugger für Web-Anwendungen" +#~ msgid "About..." +#~ msgstr "Info..." +#~ msgid "AcceptWait property cannot be modified while server is active." +#~ msgstr "" +#~ "Die Eigenschaft AcceptWait kann nicht modifiziert werden, während der " +#~ "Server aktiv ist." +#~ msgid "Accepted" +#~ msgstr "Akzeptiert" +#~ msgid "Access denied to \"%s\"" +#~ msgstr "Zugriff auf \"%s\" verweigert" +#~ msgid "Access denied." +#~ msgstr "Zugriff verweigert." +#~ msgid "Access to %s denied" +#~ msgstr "Zugriff auf %s verweigert." +#~ msgid "Access violation" +#~ msgstr "Zugriffsverletzung" +#~ msgid "Access violation at address %p, accessing address %p" +#~ msgstr "Access violation at address %p, accessing address %p" +#~ msgid "AccessRights" +#~ msgstr "Zugriffsrechte" +#~ msgid "AcreFeet" +#~ msgstr "Morgen/Fuß" +#~ msgid "AcreInches" +#~ msgstr "Morgen/Zoll" +#~ msgid "Acres" +#~ msgstr "Morgen" +#~ msgid "Action can't redirect to blank URL" +#~ msgstr "Aktion kann nicht zu leerer URL umleiten" +#~ msgid "Action can't respone to unknown HTTP method" +#~ msgstr "Aktion kann nicht auf unbekannte HTTP -Methode antworten" +#~ msgid "Action does not provide response" +#~ msgstr "Aktion sieht keine Antwort vor" +#~ msgid "ActionManager must first be assigned" +#~ msgstr "ActionManager muss zuerst zugewiesen werden" +#~ msgid "Actions" +#~ msgstr "Aktionen" +#~ msgid "Active Border" +#~ msgstr "Aktiver Rahmen" +#~ msgid "Active Caption" +#~ msgstr "Aktive Titelleiste" +#~ msgid "Adapter Request not handled: %0:s, %1:s" +#~ msgstr "Adapteranforderung nicht behandelt: %0:s, %1:s" +#~ msgid "Add" +#~ msgstr "Hinzufügen" +#~ msgid "Add &SubItem" +#~ msgstr "Hin&zufügen" +#~ msgid "Add Actions" +#~ msgstr "Aktionen hinzufügen" +#~ msgid "Add Actions..." +#~ msgstr "Aktionen hinzufügen..." +#~ msgid "Add All Actions" +#~ msgstr "Alle Aktionen hinzufügen" +#~ msgid "Add All Actions..." +#~ msgstr "Alle Aktionen hinzufügen..." +#~ msgid "Add All Columns" +#~ msgstr "Alle Spalten hinzufügen" +#~ msgid "Add All Commands" +#~ msgstr "Alle Befehle hinzufügen" +#~ msgid "Add All Fields" +#~ msgstr "Alle Felder hinzufügen" +#~ msgid "Add All Params" +#~ msgstr "Alle Parameter hinzufügen" +#~ msgid "Add Columns" +#~ msgstr "Spalten hinzufügen" +#~ msgid "Add Columns..." +#~ msgstr "Spalten hinzufügen..." +#~ msgid "Add Commands" +#~ msgstr "Befehle hinzufügen" +#~ msgid "Add Commands..." +#~ msgstr "Befehle hinzufügen..." +#~ msgid "Add Fields..." +#~ msgstr "Felder hinzufügen..." +#~ msgid "Add Images" +#~ msgstr "Bilder hinzufügen" +#~ msgid "Add Params..." +#~ msgstr "Parameter hinzufügen..." +#~ msgid "Add item" +#~ msgstr "Eintrag hinzufügen" +#~ msgid "Additional" +#~ msgstr "Zusätzlich" +#~ msgid "Address already in use." +#~ msgstr "Die Adresse ist bereits in Gebrauch." +#~ msgid "Address family not supported by protocol family." +#~ msgstr "Die Adressfamilie wird von der Protokollfamilie nicht unterstützt." +#~ msgid "Address type not supported." +#~ msgstr "Der Adresstyp wird nicht unterstützt." +#~ msgid "Administrator" +#~ msgstr "Administrator" +#~ msgid "Alert: action must be taken immediately" +#~ msgstr "Alarm: Es muss sofort etwas getan werden" +#~ msgid "Align &Left" +#~ msgstr "&Links ausrichten" +#~ msgid "Align &Right" +#~ msgstr "&Rechts ausrichten" +#~ msgid "Align Left|Aligns text at the left indent" +#~ msgstr "Links ausrichten|Text linksbündig ausrichten" +#~ msgid "Align Right|Aligns text at the right indent" +#~ msgstr "Rechts ausrichten|Text rechtsbündig ausrichten" +#~ msgid "All Files (*)|*" +#~ msgstr "Alle Dateien(*)|*" +#~ msgid "All Files (*)|*|" +#~ msgstr "Alle Dateien (*)|*|" +#~ msgid "All Files (*.*)|*.*" +#~ msgstr "Alle Dateien(*.*)|*.*" +#~ msgid "All Files (*.*)|*.*|" +#~ msgstr "Alle Dateien (*.*)|*.*|" +#~ msgid "All Files(*)" +#~ msgstr "Alle Dateien (*)" +#~ msgid "Allowed login attempts exceeded, good bye." +#~ msgstr "Die Anzahl erlaubter Anmeldeversuche wurde überschritten, goodbye." +#~ msgid "Already connected." +#~ msgstr "Verbindung besteht bereits." +#~ msgid "An About Box is not available for this control" +#~ msgstr "Für dieses Element gibt es kein Info-Fenster" +#~ msgid "An unknown error occurred while processing the certificate." +#~ msgstr "Beim Bearbeiten des Zertifikats ist ein Fehler aufgetreten." +#~ msgid "Angstroms" +#~ msgstr "Angström" +#~ msgid "Anonymous login OK, send e-mail as password." +#~ msgstr "Anonyme Anmeldung OK, E-Mail als Passwort senden." +#~ msgid "Anonymous user logged in, proceed." +#~ msgstr "Anonymer Benutzer angemeldet, weiter." +#~ msgid "Any" +#~ msgstr "Any" +#~ msgid "Application Workspace" +#~ msgstr "Anwendungsarbeitsbereich" +#~ msgid "Apply &to all toolbars" +#~ msgstr "&Für alle Symbolleisten verwenden" +#~ msgid "Apply caption options &to all toolbars" +#~ msgstr "Optionen für alle Symbolleisten verwenden" +#~ msgid "Aqua" +#~ msgstr "Aquamarin" +#~ msgid "Are you sure you want to delete \"%s\"?" +#~ msgstr "Wollen Sie \"%s\" wirklich löschen?" +#~ msgid "Are you sure you want to delete these %d items?" +#~ msgstr "Wollen Sie diese %d Einträge wirklich löschen?" +#~ msgid "Area" +#~ msgstr "Fläche" +#~ msgid "Ares" +#~ msgstr "Ar" +#~ msgid "Array Node: %s has too many elements" +#~ msgstr "Array-Knoten: %s hat zu viele Elemente" +#~ msgid "Array type expected. Node %s" +#~ msgstr "Array-Typ erwartet. Knoten %s" +#~ msgid "Assigned Port value %d is invalid" +#~ msgstr "Zugewiesener Wert für Port %d ist ungültig" +#~ msgid "AstronomicalUnits" +#~ msgstr "Astronomische Einheiten" +#~ msgid "Attempt to %s while the HL7 Component is not working" +#~ msgstr "Versuch zu %s wobei die HL7-Komponente nicht funktioniert" +#~ msgid "Attempting to put items into a virtual style listbox" +#~ msgstr "Versuch, Elemente in ein virtuelles Stillistenfeld einzufügen" +#~ msgid "Attribute already associated with another element" +#~ msgstr "Das Attribut ist bereits mit einem anderen Element verknüpft" +#~ msgid "Attributes" +#~ msgstr "Attribute" +#~ msgid "Attributes are not supported on this node type" +#~ msgstr "Attribute werden bei diesem Knotentyp nicht unterstützt" +#~ msgid "Authenticated" +#~ msgstr "Authentifiziert" +#~ msgid "Authentication Failed" +#~ msgstr "Authentifizierung fehlgeschlagen" +#~ msgid "Authentication error to socks server." +#~ msgstr "Authentifizierungsfehler bei Socks-Server." +#~ msgid "Auto Preview" +#~ msgstr "Schnellvorschau" +#~ msgid "Avg Response Time:" +#~ msgstr "Mittlere Antwortzeit:" +#~ msgid "BCD overflow" +#~ msgstr "BCD-Überlauf" +#~ msgid "Back" +#~ msgstr "Zurück" +#~ msgid "BackTab" +#~ msgstr "RückTab" +#~ msgid "Background" +#~ msgstr "Hintergrund" +#~ msgid "Backspace" +#~ msgstr "Rück" +#~ msgid "Backup Database files" +#~ msgstr "Datenbankdateien sichern" +#~ msgid "Bad Gateway" +#~ msgstr "Falsches Gateway" +#~ msgid "Bad Request" +#~ msgstr "Falsche Anforderung" +#~ msgid "Bad address." +#~ msgstr "Falsche Adresse." +#~ msgid "Bad file number." +#~ msgstr "Falsche Dateinummer." +#~ msgid "Bad protocol option." +#~ msgstr "Falsche Protokolloption." +#~ msgid "Bad variant type %x" +#~ msgstr "Falscher Variant-Typ %x" +#~ msgid "Binding Editor" +#~ msgstr "Editor für Bindungen" +#~ msgid "Bitmaps (*.bmp)|*.bmp" +#~ msgstr "Bitmaps (*.bmp)|*.bmp" +#~ msgid "Black" +#~ msgstr "Schwarz" +#~ msgid "Blue" +#~ msgstr "Blau" +#~ msgid "Body Text Editor" +#~ msgstr "Editor für Textkörper" +#~ msgid "Boolean parameter expected" +#~ msgstr "Boolescher Parameter erwartet" +#~ msgid "Bring to Front" +#~ msgstr "Nach vorne setzen" +#~ msgid "Browse URL" +#~ msgstr "Internet" +#~ msgid "BrowseAction" +#~ msgstr "BrowseAction" +#~ msgid "Build" +#~ msgstr "Erzeugen" +#~ msgid "Built-in Type" +#~ msgstr "Integrierter Typ" +#~ msgid "Bullets|Inserts a bullet on the current line" +#~ msgstr "" +#~ "Aufzählungszeichen|In die aktuielle Zeile ein Aufzählungszeichen einfügen" +#~ msgid "Button Face" +#~ msgstr "Schalterfläche" +#~ msgid "Button Highlight" +#~ msgstr "Schalterhervorhebung" +#~ msgid "Button Shadow" +#~ msgstr "Schalterschatten" +#~ msgid "Button Text" +#~ msgstr "Schaltertext" +#~ msgid "Byte index out of range." +#~ msgstr "Byte-Index außerhalb des gültigen Bereichs." +#~ msgid "" +#~ "ByteBool, WordBool and LongBool cannot be exposed by WebServices. Please " +#~ "use 'Boolean'" +#~ msgstr "" +#~ "ByteBool, WordBool und LongBool käönnen durch WebServices nicht " +#~ "dargestellt werden. Bitte verwenden Sie 'Boolean'" +#~ msgid "C&lose" +#~ msgstr "S&chließen" +#~ msgid "CRC Failed" +#~ msgstr "CRC fehlgeschlagen" +#~ msgid "Call to %s.GetByte [property Bytes] with index <> [0..%d]" +#~ msgstr "Aufruf von %s.GetByte [property Bytes] mit Index <> [0..%d]" +#~ msgid "Can not bind in port range (%d - %d)" +#~ msgstr "Port-Beriech (%d - %d) kann nicht eingebunden werden" +#~ msgid "Can not change credentials after handle aquired. Use Release first" +#~ msgstr "" +#~ "Beglaubigung kann nicht nach Holen des Handle geändert werden. Zuerst " +#~ "Release benutzen" +#~ msgid "Can't execute %s %d" +#~ msgstr "Ausführung nicht möglich von %s %d" +#~ msgid "Can't find included page: %s" +#~ msgstr "Einbezogene Seite %s nicht gefunden" +#~ msgid "Can't open data connection." +#~ msgstr "Datenverbindung klann nicht geöffnet werden." +#~ msgid "Cannot allocate socket." +#~ msgstr "Socket kann nicht zugewiesen werden." +#~ msgid "" +#~ "Cannot assign a subitem to an actionbar when one of it's parent's is " +#~ "already assigned to an actionbar" +#~ msgstr "" +#~ "Unterelement kann nicht zu Aktionsleiste hinzugefügt werden, wenn ein " +#~ "übergeordnetes Element bereits einer Aktionsleiste zugewiesen ist" +#~ msgid "Cannot assign requested address." +#~ msgstr "Die angeforderte Adresse kann nicht zugewiesen werden." +#~ msgid "Cannot call TerminateAndWaitFor on FreeAndTerminate threads" +#~ msgstr "" +#~ "Aufruf von TerminateAndWaitFor für FreeAndTerminate-Threads nicht möglich" +#~ msgid "Cannot change connection on Active Monitor" +#~ msgstr "Die Verbindung kann bei aktivem Monitor nicht geändert werden" +#~ msgid "Cannot change session state when the server is active." +#~ msgstr "" +#~ "Sitzungsstatus kann nicht geändert werden, während der Server aktiv ist.." +#~ msgid "Cannot change target while active." +#~ msgstr "Ziel kann in aktivem Zustand nicht geändert werden." +#~ msgid "Cannot convert NAN to TBcd value" +#~ msgstr "NAN kann nicht zu TBcd-Wert konvertiert werden" +#~ msgid "Cannot convert empty string to TBcd value" +#~ msgstr "Leerer String kann nicht in TBcd-Wert konvertiert werden" +#~ msgid "Cannot convert from the specified type" +#~ msgstr "Konvertierung des angegebenen Typs kann nicht durchgeführt werden" +#~ msgid "Cannot convert scientific notation to TBcd value" +#~ msgstr "" +#~ "Wissenschaftliche Notation kann nicht zu TBcd-Wert konvertiert werden" +#~ msgid "Cannot convert to TBcd: string has more than 64 digits: %s" +#~ msgstr "" +#~ "Keine Konvertierung nach TBcd: String enthält mehr als 64 Ziffern: %s" +#~ msgid "Cannot convert to the specified type" +#~ msgstr "Konvertierung in den angegebenen Typ kann nicht durchgeführt werden" +#~ msgid "Cannot create a method for an unnamed component" +#~ msgstr "Für eine unbenannte Komponente kann keine Methode erstellt werden." +#~ msgid "Cannot create file \"%s\". %s" +#~ msgstr "Datei \"%s\" kann nicht erstellt werden. %s" +#~ msgid "Cannot create script engine: %s. Error: %x" +#~ msgstr "Script-Engine kann nicht erzeugt werden: %s. Fehler: %x" +#~ msgid "Cannot find TableName in CommandText" +#~ msgstr "Eigenschaft TableName in CommandText nicht gefunden" +#~ msgid "Cannot find node referenced by ID %s" +#~ msgstr "Von ID %s referenzierten Knoten nicht gefunden" +#~ msgid "Cannot focus a disabled or invisible window (%s)" +#~ msgstr "" +#~ "Ein deaktiviertes oder unsichtbares Fenster (%s) kann den Fokus nicht " +#~ "erhalten" +#~ msgid "Cannot initialize script engine" +#~ msgstr "Script-Engine kann nicht initialisiert werden" +#~ msgid "Cannot insert child node" +#~ msgstr "Untergeordneter Knoten kann nicht eingefügt werden" +#~ msgid "Cannot open detail table with master closed" +#~ msgstr "" +#~ "Detailtabelle kann nicht geöffnet werden, wenn die Haupttabelle " +#~ "geschlossen ist." +#~ msgid "Cannot open file \"%s\". %s" +#~ msgstr "Datei %s kann nicht geöffnet werden. %s" +#~ msgid "Cannot perform task while server is active." +#~ msgstr "Task kann nicht ausgeführt werden, während der Server aktiv ist." +#~ msgid "Cannot perform this operation on a closed connection" +#~ msgstr "" +#~ "Bei einer geschlossenen Verbindung ist diese Operation nicht möglich" +#~ msgid "Cannot perform this operation on an open connection" +#~ msgstr "Bei einer geöffneten Verbindung ist diese Operation nicht möglich" +#~ msgid "Cannot read WideString from odd byte position" +#~ msgstr "" +#~ "WideString kann nicht von einer ungeraden Byte-Position aus gelesen werden" +#~ msgid "" +#~ "Cannot read directory:\n" +#~ "\"%s\"" +#~ msgstr "" +#~ "Verzeichnis kann nicht gelesen werden:\n" +#~ "\"%s\"" +#~ msgid "Cannot send or receive after socket is closed." +#~ msgstr "" +#~ "Nach Schließen des Socket kann weder gesendet noch empfangen werden." +#~ msgid "Cannot set Clipped property while painting" +#~ msgstr "" +#~ "Die Eigenschaft Clipped kann während des Zeichnens nicht geändert werden" +#~ msgid "Cannot write WideString to odd byte position" +#~ msgstr "" +#~ "WideString kann nicht an eine ungerade Byte-Position geschrieben werden" +#~ msgid "Cannt connect to the Master server" +#~ msgstr "Zum Haupt-Server kann keine Verbindung hergestellt werden" +#~ msgid "Capacity cannot be less than size" +#~ msgstr "Die Kapazität darf nicht geringer als die Größe sein" +#~ msgid "Caption Text" +#~ msgstr "Titeltext" +#~ msgid "Cascade" +#~ msgstr "Überlappend" +#~ msgid "Cate&gories:" +#~ msgstr "&Kategorien:" +#~ msgid "Celsius" +#~ msgstr "Celsius" +#~ msgid "Centares" +#~ msgstr "Zentarien" +#~ msgid "Center|Centers text between margins" +#~ msgstr "Zentriert|Text zentriert ausrichten" +#~ msgid "CentiLiters" +#~ msgstr "Zentiliter" +#~ msgid "Centigrams" +#~ msgstr "Zentigramm" +#~ msgid "Centimeters" +#~ msgstr "Zentimeter" +#~ msgid "Centuries" +#~ msgstr "Jahrhundert" +#~ msgid "Chains" +#~ msgstr "Messkette" +#~ msgid "Change view" +#~ msgstr "Ansicht ändern" +#~ msgid "" +#~ "CheckSynchronize called from thread $%x, which is NOT the main thread" +#~ msgstr "" +#~ "CheckSynchronize wurde vom Thread $%x aufgerufen, der NICHT der Haupt-" +#~ "Thread ist." +#~ msgid "ChildName cannot be blank" +#~ msgstr "ChildName muss angegeben werden" +#~ msgid "Chunk Started" +#~ msgstr "Chunk gestartet" +#~ msgid "Circular provider references not allowed." +#~ msgstr "Zirkuläre Provider-Referenzen nicht erlaubt." +#~ msgid "Circular reference to Connection not allowed" +#~ msgstr "Zirkulärer Verweis auf Verbindung nicht zulässig" +#~ msgid "Circular references not allowed" +#~ msgstr "Zirkuläre Verweise sind nicht gestattet" +#~ msgid "Class %s could not create QT widget" +#~ msgstr "Klasse %s konnte kein QT-Widget erzeugen" +#~ msgid "Class %s does not implement interface GUID %s" +#~ msgstr "Klasse %s implementiert Schnittstelle GUID %s nicht" +#~ msgid "Class %s is not applicable to this module" +#~ msgstr "Klasse %s kann bei diesem Modul nicht angewendet werden" +#~ msgid "Class not registered" +#~ msgstr "Klasse nicht registriert" +#~ msgid "" +#~ "Classes that represent scalar types must descend from TRemotableXS, %s " +#~ "does not" +#~ msgstr "" +#~ "Klassen, die Skalartypen repräsentieren, müssen von TRemotableXS " +#~ "abgeleitet worden sein; %s ist es nicht" +#~ msgid "Clear" +#~ msgstr "Löschen" +#~ msgid "Clear Selection" +#~ msgstr "Liste" +#~ msgid "CloneConnection invalid: distinct ClientDataSet descendents" +#~ msgstr "CloneConnection ungültig: verschiedene ClientDataSet-Nachkommen" +#~ msgid "Close" +#~ msgstr "Schließen" +#~ msgid "Closing data connection." +#~ msgstr "Datenverbindung wird geschlossen." +#~ msgid "Code" +#~ msgstr "Code" +#~ msgid "Codeset conversion failure" +#~ msgstr "Fehler bei Codeset-Konvertierung" +#~ msgid "Color Select" +#~ msgstr "Dialog" +#~ msgid "Color depth must be 1, 8 or 32 bpp" +#~ msgstr "Die Farbtiefe muss 1, 8 oder 32 bpp betragen" +#~ msgid "Command Not Handled: %s" +#~ msgstr "Anweisung nicht behandelt: %s" +#~ msgid "Command Not Recognised" +#~ msgstr "Anweisung nicht erkannt" +#~ msgid "Command not recognized" +#~ msgstr "Anweisung nicht erkannt" +#~ msgid "Command not supported." +#~ msgstr "Anweisung nicht unterstützt" +#~ msgid "CompleteAuthToken is not supported" +#~ msgstr "CompleteAuthToken nicht unterstützt" +#~ msgid "Component %s not found" +#~ msgstr "Komponente %s nicht gefunden" +#~ msgid "Component does not support scripting. Class: %0:s, Name: %1:s" +#~ msgstr "" +#~ "Komponente unterstützt das Scripting nicht. Klasse: %0:s, Name: %1:s" +#~ msgid "" +#~ "Component is in Asynchronous mode but OnMessageArrive has not been hooked" +#~ msgstr "" +#~ "Komponente ist in asynchronen Modus, aber OnMessageArrive wurde nicht " +#~ "eingehängt (hooked)" +#~ msgid "" +#~ "Component is in Synchronous mode but OnMessageReceive has not been hooked" +#~ msgstr "" +#~ "Komponente ist in synchronen Modus, aber OnMessageReceive wurde nicht " +#~ "eingehängt (hooked)" +#~ msgid "Component name '%s' exceeds 64 character limit" +#~ msgstr "Komponentenname '%s' überschreitet 64 Zeichen" +#~ msgid "" +#~ "Component was expected to implement IInterfaceComponentReference for " +#~ "ValuesList support" +#~ msgstr "" +#~ "Es wurde erwartet, dass die Komponente zur Unterstützung von ValuesList " +#~ "IInterfaceComponentReference implementiert" +#~ msgid "Compression error" +#~ msgstr "Kompressionsfehler" +#~ msgid "Configuration file %s not found" +#~ msgstr "Konfigurationsdatei %s nicht gefunden" +#~ msgid "Confirm file deletion" +#~ msgstr "Bestätigung" +#~ msgid "Conflict" +#~ msgstr "Konflikt" +#~ msgid "Conflicting Value" +#~ msgstr "Widersprüchliche Werte" +#~ msgid "Connect timed out." +#~ msgstr "Zeitüberschreitung der Verbindung." +#~ msgid "Connected" +#~ msgstr "Verbunden" +#~ msgid "Connected." +#~ msgstr "Verbunden." +#~ msgid "Connecting" +#~ msgstr "Herstellen der Verbindung" +#~ msgid "Connecting to %s." +#~ msgstr "Verbinden mit %s." +#~ msgid "Connection" +#~ msgstr "Verbindung" +#~ msgid "Connection Closed Gracefully." +#~ msgstr "Die Verbindung wurde erfolgreich geschlossen." +#~ msgid "Connection established" +#~ msgstr "Verbindung hergestellt" +#~ msgid "Connection explicitly refused by NNTP server." +#~ msgstr "Die Verbindung wurde explizit vom NNTP-Server abgelehnt." +#~ msgid "Connection name missing" +#~ msgstr "Name der Verbindung fehlt" +#~ msgid "Connection not allowed by ruleset." +#~ msgstr "Die Verbindung wird von der Regelmenge nicht zugelassen." +#~ msgid "Connection not allowed to TConnectionBroker" +#~ msgstr "Verbindung für TConnectionBroker nicht gestattet" +#~ msgid "Connection refused." +#~ msgstr "Verbindung abgelehnt." +#~ msgid "Connection reset by peer." +#~ msgstr "Die Verbindung wurde von Peer zurückgesetzt." +#~ msgid "Connection timed out." +#~ msgstr "Zeitüberschreitung bei Verbindung." +#~ msgid "Content Length" +#~ msgstr "Inhaltslänge" +#~ msgid "Content-Length header not found" +#~ msgstr "Inhaltslängen-Header nicht gefunden" +#~ msgid "ContentModel not set" +#~ msgstr "ContentModel nicht gesetzt" +#~ msgid "Continue" +#~ msgstr "Fortsetzen" +#~ msgid "Continue delete operation?" +#~ msgstr "Soll der Löschvorgang fortgesetzt werden?" +#~ msgid "Control" +#~ msgstr "Element" +#~ msgid "Control '%s' has no parent widget" +#~ msgstr "Element '%s' besitzt kein übergeordnetes Widget" +#~ msgid "Control file save to %s" +#~ msgstr "Steuerungsdatei speichern in %s" +#~ msgid "Conversion family (%s) already registered" +#~ msgstr "Konvertierungsfamilie (%s) bereits registriert" +#~ msgid "" +#~ "Conversion from class %s to SOAP is not supported - SOAP classes must " +#~ "derive from TRemotable" +#~ msgstr "" +#~ "Die Konvertierung von Klasse %s zu SOAP wird nicht unterstützt - SOAP-" +#~ "Klassen müssen von TRemotable abgeleitet worden sein" +#~ msgid "Conversion type (%s) already registered in %s" +#~ msgstr "Konvertierungstyp (%s) bereits registriert in %s" +#~ msgid "Copy" +#~ msgstr "Kopieren" +#~ msgid "Copy Selection" +#~ msgstr "Liste" +#~ msgid "" +#~ "Copyright (c) 1993 - 2002\n" +#~ "Kudzu (Chad Z. Hower)\n" +#~ "and the\n" +#~ "Indy Pit Crew" +#~ msgstr "" +#~ "Copyright (c) 1993 - 2002\n" +#~ "Kudzu (Chad Z. Hower)\n" +#~ "und die\n" +#~ "Indy Boxen-Crew" +#~ msgid "Copy|Copies the selection and puts it on the Clipboard" +#~ msgstr "Kopieren|Markiertes Objekt in die Zwischenablage kopieren" +#~ msgid "CordFeet" +#~ msgstr "Klasterfuß" +#~ msgid "Cords" +#~ msgstr "Klaster" +#~ msgid "Correct" +#~ msgstr "Korrekt" +#~ msgid "Could not bind socket. Address and port are already in use." +#~ msgstr "" +#~ "Socket konnte nicht gebunden werden. Adresse und Port werden bereits " +#~ "benutzt." +#~ msgid "Could not convert variant of type (%s) into type (%s)" +#~ msgstr "Variante des Typs (%s) konnte nicht in Typ (%s) konvertiert werden" +#~ msgid "Could not create XMLDocument" +#~ msgstr "XML-Dokument konnte nicht erzeugt werden" +#~ msgid "Could not find server in ObjectManager list" +#~ msgstr "Der Server kann in der ObjectManager-Liste nicht gefunden werden" +#~ msgid "Could not load SSL library." +#~ msgstr "SSL.-Bibliothek konnte nicht geladen werden." +#~ msgid "Could not load certificate." +#~ msgstr "Zertifikat konnte nicht geladen werden." +#~ msgid "Could not load key, check password." +#~ msgstr "" +#~ "Der Schlüssel konnte nicht geladen werden; überprüfen Sie das Passwort." +#~ msgid "Could not load root certificate." +#~ msgstr "Stammzertifikat konnte nicht geladen werden." +#~ msgid "Could not open file " +#~ msgstr "Datei kann nicht geöffnet werden: " +#~ msgid "Could not parse %s" +#~ msgstr "%s konnte nicht analysiert werden" +#~ msgid "Could not parse SQL TimeStamp string" +#~ msgstr "SQL-TimeStamp-String konnte nicht analysiert werden" +#~ msgid "Could not parse imaginary portion" +#~ msgstr "Imaginärer Anteil konnte nicht analysiert werden" +#~ msgid "Could not parse real portion" +#~ msgstr "Realer Anteil konnte nicht analysiert werden" +#~ msgid "Could not parse required '%s' symbol" +#~ msgstr "Erforderliches '%s'-Symbol kann nicht analysiert werden" +#~ msgid "Could not parse required '+' (or '-') symbol" +#~ msgstr "Erforderliches '+' (oder '-') Symbol konnte nicht analysiert werden" +#~ msgid "" +#~ "Cr&op\n" +#~ "St&retch\n" +#~ "C&enter\n" +#~ msgstr "" +#~ "Cr&op\n" +#~ "St&retch\n" +#~ "C&enter\n" +#~ msgid "Cream" +#~ msgstr "Creme" +#~ msgid "Create new directory" +#~ msgstr "Neues Verzeichnis erstellen" +#~ msgid "Created" +#~ msgstr "Erstellt" +#~ msgid "Creates a WebSnap Application" +#~ msgstr "WebSnap-Anwendung erzeugen" +#~ msgid "Creates a WebSnap Data Module" +#~ msgstr "WebSnap-Datenmodul erzeugen" +#~ msgid "Creates a WebSnap Page Module" +#~ msgstr "WebSnap-Seitenmodul erzeugen" +#~ msgid "Critical: critical conditions" +#~ msgstr "Kritisch: Kritischer Zustand" +#~ msgid "CubicCentimeters" +#~ msgstr "Kubikzentimeter" +#~ msgid "CubicDecameters" +#~ msgstr "Kubikdekameter" +#~ msgid "CubicDecimeters" +#~ msgstr "Kubikdezimeter" +#~ msgid "CubicFeet" +#~ msgstr "Kubikfuß" +#~ msgid "CubicHectometers" +#~ msgstr "Kubikhektometer" +#~ msgid "CubicInches" +#~ msgstr "Kubikzoll" +#~ msgid "CubicKilometers" +#~ msgstr "Kubikkilometer" +#~ msgid "CubicMeters" +#~ msgstr "Kubikmeter" +#~ msgid "CubicMiles" +#~ msgstr "Kubikmeilen" +#~ msgid "CubicMillimeters" +#~ msgstr "Kubikmillimeter" +#~ msgid "CubicYards" +#~ msgstr "Kubik-Yard" +#~ msgid "Cubits" +#~ msgstr "Elle" +#~ msgid "Cursor not returned from Query" +#~ msgstr "Cursor nicht aus Abfrage zurückgekehrt" +#~ msgid "Custom message interpretation failed" +#~ msgstr "Individuelle Botschaftsinterpretation ist fehlgeschlagen" +#~ msgid "Custom variant type ($%.4x) already used by %s" +#~ msgstr "Benutzerdefinierter Variant-Typ ($%.4x) bereits benutzt von %s" +#~ msgid "Custom variant type ($%.4x) is not usable" +#~ msgstr "Benutzerdefinierter Variant-Typ ($%.4x) nicht brauchbar" +#~ msgid "Custom variant type ($%.4x) is out of range" +#~ msgstr "" +#~ "Benutzerdefinierter Variant-Typ ($%.4x) außerhalb des gültigen Bereichs" +#~ msgid "Custom variant type (%s%.4x) already used by %s" +#~ msgstr "Benutzerdefinierter Variant-Typ (%s%.4x) bereits benutzt von %s" +#~ msgid "Custom variant type (%s%.4x) is not usable" +#~ msgstr "Benutzerdefinierter Variant-Typ (%s%.4x) nicht brauchbar" +#~ msgid "Custom variant type (%s%.4x) is out of range" +#~ msgstr "" +#~ "Benutzerdefinierter Variant-Typ (%s%.4x) außerhalb des gültigen Bereichs" +#~ msgid "Custom..." +#~ msgstr "Individuell..." +#~ msgid "Customize" +#~ msgstr "Anpassen" +#~ msgid "Cut" +#~ msgstr "Ausschneiden" +#~ msgid "Cut|Cuts the selection and puts it on the Clipboard" +#~ msgstr "Ausschneiden|Markiertes Objekt in die Zwischenablage verschieben" +#~ msgid "DBX Error: Command not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: Befehl nicht gefunden, Fehlermeldung kann nicht abgerufen " +#~ "werden" +#~ msgid "DBX Error: Connection not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: Verbindung nicht gefunden, Fehlermeldung kann nicht abgerufen " +#~ "werden" +#~ msgid "DBX Error: Cursor not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: Cursor nicht gefunden, Fehlermeldung kann nicht abgerufen " +#~ "werden" +#~ msgid "" +#~ "DBX Error: MetadataObject not found, error message cannot be retrieved" +#~ msgstr "" +#~ "DBX-Fehler: MetadataObject nicht gefunden, Fehlermeldung kann nicht " +#~ "abgerufen werden" +#~ msgid "DBX Error: No Mapping for Error Code Found" +#~ msgstr "DBX-Fehler: Keine Zuordnung des Fehlercodes gefunden" +#~ msgid "DLL/Shared Library Name not Set" +#~ msgstr "Name für DLL/Gemeinsame Bibliothek ist nicht gesetzt" +#~ msgid "DNS Server Reports Query Format Error" +#~ msgstr "Der DNS-Server meldet einen Fehler im Abfrageformat" +#~ msgid "DNS Server Reports Query Name Error" +#~ msgstr "Der DNS-Server meldet einen Fehler im Abfragenamen" +#~ msgid "DNS Server Reports Query Not Implemented Error" +#~ msgstr "" +#~ "Der DNS-Server meldet einen Fehler, dass die Abfrage nicht implementiert " +#~ "ist" +#~ msgid "DNS Server Reports Query Refused Error" +#~ msgstr "" +#~ "Der DNS-Server meldet einen Fehler, dass die Abfrage zurückgewiesen wurde" +#~ msgid "DNS Server Reports Query Server Error" +#~ msgstr "Der DNS-Server meldet einen Fehler beim Abfrage-Server" +#~ msgid "DOM Error: " +#~ msgstr "DOM-Fehler: " +#~ msgid "DOM Implementation does not support IDOMParseOptions" +#~ msgstr "DOM-Implementation unterstützt nicht IDOMParseOptions" +#~ msgid "DPB Constant (%s) is unknown" +#~ msgstr "DPB-Konstante (%s) ist unbekannt." +#~ msgid "DTD to XML Schema Translator (.dtd <-> .xsd)" +#~ msgstr "Übersetzer DTD nach XML-Schema (.dtd <-> .xsd)" +#~ msgid "Data Access" +#~ msgstr "Datenzugriff" +#~ msgid "Data Modification is not permitted" +#~ msgstr "Datenmodifikation ist nicht zulässig" +#~ msgid "Data Packet" +#~ msgstr "Datenpaket" +#~ msgid "Data connection already open; transfer starting." +#~ msgstr "Datenverbindung besteht bereits; Transfer wird gestartet." +#~ msgid "Data connection closed abnormally." +#~ msgstr "Datenverbindung wurde abnormal geschlossen." +#~ msgid "Data connection open; no transfer in progress." +#~ msgstr "Datenverbindung besteht bereits; kein Transfer läuft." +#~ msgid "Data file saved to %s" +#~ msgstr "Datendatei gespeichert in %s" +#~ msgid "DataSet is nil" +#~ msgstr "DataSet ist nil" +#~ msgid "Database Files|*.gdb" +#~ msgstr "Datenbankdateien|*.gdb" +#~ msgid "Database Parameters" +#~ msgstr "Datenbank-Parameter" +#~ msgid "" +#~ "Datatype of TypeKind: %s not supported as argument for remote invocation" +#~ msgstr "" +#~ "Datentyp von TypeKind: %s wird als Argument für Remote-Aufruf nicht " +#~ "unterstützt" +#~ msgid "Date" +#~ msgstr "Datum" +#~ msgid "Date Modified" +#~ msgstr "Datum geändert" +#~ msgid "DateTime" +#~ msgstr "Datum/Uhrzeit" +#~ msgid "Days" +#~ msgstr "Tag" +#~ msgid "De&lete" +#~ msgstr "&Löschen" +#~ msgid "Debug: debug-level messages" +#~ msgstr "Debug: debug-level-Botschaften" +#~ msgid "DecaLiters" +#~ msgstr "Dekaliter" +#~ msgid "Decades" +#~ msgstr "Dekade" +#~ msgid "Decagrams" +#~ msgstr "Dekagramm" +#~ msgid "Decameters" +#~ msgstr "Dekameter" +#~ msgid "Decasteres" +#~ msgstr "Dekaster" +#~ msgid "DeciLiters" +#~ msgstr "Deziliter" +#~ msgid "Decigrams" +#~ msgstr "Dezigramm" +#~ msgid "Decimeters" +#~ msgstr "Dezimeter" +#~ msgid "Decisteres" +#~ msgstr "Dezister" +#~ msgid "Decompression error" +#~ msgstr "Dekompressionsfehler" +#~ msgid "Default URL:" +#~ msgstr "Standard-URL:" +#~ msgid "Delete" +#~ msgstr "Löschen" +#~ msgid "Delete Selection" +#~ msgstr "Liste" +#~ msgid "Delete existing components?" +#~ msgstr "Existierende Komponenten löschen?" +#~ msgid "Deleted" +#~ msgstr "Gelöscht" +#~ msgid "Delete|Erases the selection" +#~ msgstr "Löschen|Auswahl löschen" +#~ msgid "Delimiter and QuoteChar properties cannot have the same value" +#~ msgstr "" +#~ "Die Eigenschaften Delimiter und QuoteChar dürfen nicht denselben Wert " +#~ "besitzen" +#~ msgid "DelphiException %s" +#~ msgstr "DelphiException %s" +#~ msgid "Demos Coordinator" +#~ msgstr "Demos-Koordinator" +#~ msgid "Description" +#~ msgstr "Beschreibung" +#~ msgid "Destination address required." +#~ msgstr "Zieladresse erforderlich." +#~ msgid "Destination file already exists." +#~ msgstr "Die Zieldatei existiert bereits." +#~ msgid "DestinationDirectory is not set" +#~ msgstr "DestinationDirectory nicht gesetzt" +#~ msgid "Detaul view" +#~ msgstr "Detailansicht" +#~ msgid "Dialog" +#~ msgstr "Dialog" +#~ msgid "Direction" +#~ msgstr "Richtung" +#~ msgid "Directory" +#~ msgstr "Verzeichnis" +#~ msgid "Directory \"%s\" is not empty." +#~ msgstr "Verzeichnis \"%s\" ist nicht leer." +#~ msgid "Directory %s does not exist" +#~ msgstr "Verzeichnis %s ist nicht vorhanden" +#~ msgid "Directory not empty" +#~ msgstr "Verzeichnis ist nicht leer" +#~ msgid "Disconnect" +#~ msgstr "Verbindung trennen" +#~ msgid "Disconnected." +#~ msgstr "Verbindung aufgehoben." +#~ msgid "Disconnecting." +#~ msgstr "Verbindung wird getrennt." +#~ msgid "Disk Quota Exceeded." +#~ msgstr "Festplattenkontingent überschritten." +#~ msgid "Dispatch methods do not support more than 64 parameters" +#~ msgstr "Dispatch-Methoden unterstützen maximal 64 Parameter." +#~ msgid "Dispatching blank page name" +#~ msgstr "Weiterleiten eines leeren Seitennamens" +#~ msgid "Distance" +#~ msgstr "Entfernung" +#~ msgid "Distribution Coordinator" +#~ msgstr "Distributions-Koordinator" +#~ msgid "Do AcquireCredentialsHandle first" +#~ msgstr "Erst AcquireCredentialsHandle" +#~ msgid "Do not allow connctions now" +#~ msgstr "Verbindungen jetzt nicht zulassen" +#~ msgid "DocumentElement %s:%s expected, %s:%s found" +#~ msgstr "Dokumentelement %s:%s erwartet, %s:%s gefunden" +#~ msgid "Documentation" +#~ msgstr "Dokumentation" +#~ msgid "Documentation Coordinator" +#~ msgstr "Dokumentationskoordinator" +#~ msgid "Double parameter expected" +#~ msgstr "Doppelparameter erwartet" +#~ msgid "Download from URL" +#~ msgstr "Internet" +#~ msgid "Drag and Drop" +#~ msgstr "Drag und Drop" +#~ msgid "Drag to create Separators" +#~ msgstr "Ziehen für das Erstellen von Separatoren" +#~ msgid "Drams" +#~ msgstr "Drachme" +#~ msgid "Drawings" +#~ msgstr "Zeichnungen" +#~ msgid "" +#~ "Drive %s does not exist.\n" +#~ "Please verify the correct drive was given." +#~ msgstr "" +#~ "Laufwerk %s existiert nicht.\n" +#~ "Überprüfen Sie, ob das richtige Laufwerkangegeben wurde." +#~ msgid "Driver (%s) not found in Cfg file (%s)" +#~ msgstr "Treiber (%s) in der CFG-Datei (%s) nicht gefunden" +#~ msgid "Driver/Connection Registry File '%s' not found" +#~ msgstr "Registrierungsdatei '%s' für Treiber/Verbindung nicht gefunden" +#~ msgid "DryBuckets" +#~ msgstr "DryBuckets" +#~ msgid "DryBushels" +#~ msgstr "Scheffel (Trockenmaß)" +#~ msgid "DryGallons" +#~ msgstr "Gallone (Trockenmaß)" +#~ msgid "DryPecks" +#~ msgstr "Viertelscheffel (Trockenmaß)" +#~ msgid "DryPints" +#~ msgstr "Pinte (Trockenmaß)" +#~ msgid "DryQuarts" +#~ msgstr "Quart (Trockenmaß)" +#~ msgid "Duplication prototype name" +#~ msgstr "Doppelter Prototypname" +#~ msgid "E&xit" +#~ msgstr "&Beenden" +#~ msgid "E&xport..." +#~ msgstr "E&xportieren..." +#~ msgid "ERROR" +#~ msgstr "FEHLER" +#~ msgid "Edit" +#~ msgstr "Bearbeiten" +#~ msgid "Edit SQL" +#~ msgstr "SQL bearbeiten" +#~ msgid "Editing %s%s%s" +#~ msgstr "%s%s%s wird bearbeitet" +#~ msgid "Elapsed" +#~ msgstr "Vergangen" +#~ msgid "Element does not contain a single text node" +#~ msgstr "Element enthält keinen einzelnen Textknoten" +#~ msgid "Element of Array type %s has no RTTI" +#~ msgstr "Element des Array-Typs %s hat kein RTTI" +#~ msgid "Emergency: system is unusable" +#~ msgstr "Notfall: System ist unbrauchbar" +#~ msgid "Empty document" +#~ msgstr "Leeres Dokument" +#~ msgid "Encoding attachment" +#~ msgstr "Anlage wird codiert" +#~ msgid "Encoding text" +#~ msgstr "Text wird codiert" +#~ msgid "End of Status" +#~ msgstr "Ende des Status" +#~ msgid "Enter password" +#~ msgstr "Passwort eingeben" +#~ msgid "Entering Passive Mode (%s)." +#~ msgstr "Gehe in Passiv-Modus (%s)." +#~ msgid "Error Loading XML" +#~ msgstr "Fehler beim Laden von XML" +#~ msgid "Error Processing Header (%s)%s" +#~ msgstr "Fehler beim Verarbeiten von Header (%s)%s" +#~ msgid "Error accepting connection with SSL." +#~ msgstr "Fehler beim Akzeptieren der Verbindung mit SSL." +#~ msgid "Error binding data to SSL socket." +#~ msgstr "Fehler beim Binden der Daten an den SSL-Socket.." +#~ msgid "Error connecting with SSL." +#~ msgstr "Fehler bei Verbinden mit SSL." +#~ msgid "Error creating SSL context." +#~ msgstr "Fehler beim Anlegen eines SSL-Kontexts." +#~ msgid "Error creating file \"%s\"" +#~ msgstr "Fehler beim Erzeugen von Datei %s" +#~ msgid "Error creating variant or safe array" +#~ msgstr "Fehler beim Erzeugen von Variante oder sicherem Array" +#~ msgid "Error creating widget" +#~ msgstr "Fehler beim Erzeugen von Widget" +#~ msgid "Error decoding URL style (%%XX) encoded string at position %d" +#~ msgstr "" +#~ "Fehler beim Decodieren eines im URL-Stil (%%XX) codierten Strings bei " +#~ "Position %d" +#~ msgid "Error downloading URL: %s" +#~ msgstr "Fehler beim Download von URL: %s" +#~ msgid "Error geting SSL method." +#~ msgstr "Fehler beim Einlesen einer SSL-Methode." +#~ msgid "Error in parsing command." +#~ msgstr "Fehler bei der Analyse einer Anweisung." +#~ msgid "Error in transformation before send" +#~ msgstr "Fehler bei der Transformation vor dem Senden" +#~ msgid "Error loading library \"%s\": \"%s\"" +#~ msgstr "Fehler beim Laden der Bibliothek \"%s\": \"%s\"" +#~ msgid "" +#~ "Error loading previously saved settings file: %sWould you like to delete " +#~ "it?" +#~ msgstr "" +#~ "Fehler beim Laden der zuvor gespeicherten Einstellungsdatei: %sSoll die " +#~ "Datei gelöscht werden?" +#~ msgid "Error on call Winsock2 library function %s" +#~ msgstr "Fehler beim Aufruf einer Winsock2-Bibliotheksfunktion %s" +#~ msgid "Error on line %d, position %d" +#~ msgstr "Fehler in Zeile %d, Position %d" +#~ msgid "Error on loading Winsock2 library (%s)" +#~ msgstr "Fehler beim Laden einer Winsock2-Bibliothek (%s)" +#~ msgid "Error opening file" +#~ msgstr "Fehler beim Öffnen von Datei" +#~ msgid "Error reading from Mime Request Stream" +#~ msgstr "Fehler beim Lesen von Mime-Anforderungs-Stream" +#~ msgid "Error resizing ImageList" +#~ msgstr "Fehler bei der Größenänderung der ImageList" +#~ msgid "Error saving attachment." +#~ msgstr "Fehler beim Speichern der Anlage." +#~ msgid "Error saving file" +#~ msgstr "Fehler beim Speichern von Datei" +#~ msgid "Error sending mail" +#~ msgstr "Fehler beim Versenden von Mail" +#~ msgid "Error setting %s.Count" +#~ msgstr "Fehler beim Setzen von %s.Count" +#~ msgid "Error setting path: \"%s\"" +#~ msgstr "Fehler beim Festlegen des Pfades: \"%s\"" +#~ msgid "Error setting stream size" +#~ msgstr "Fehler beim Setzen der Größe des Stream" +#~ msgid "Error: " +#~ msgstr "Fehler: " +#~ msgid "Error: No program code to return request!" +#~ msgstr "Fehler: Kein Programm-Code, um die Anforderung zurückzugeben!" +#~ msgid "Error: error conditions" +#~ msgstr "Fehler: Fehlerzustand" +#~ msgid "Error: no queues defined" +#~ msgstr "Fehler: Keine Warteschlange definiert" +#~ msgid "Errors object must support the interface IIterateIntfSupport" +#~ msgstr "Fehlerobjekte müssen das Interface IIterateIntfSupport unterstützen" +#~ msgid "Event" +#~ msgstr "Ereignis" +#~ msgid "Events already registered" +#~ msgstr "Ereignisse bereits registriert" +#~ msgid "Exception in InterpretData: %s" +#~ msgstr "Exception in InterpretData: %s" +#~ msgid "Execution of action %s is not permitted" +#~ msgstr "Ausführung der Aktion %s ist nicht zulässig" +#~ msgid "Exit|Quits the application" +#~ msgstr "Beenden|Anwendung beenden" +#~ msgid "Expand" +#~ msgstr "Einblenden" +#~ msgid "Export Images" +#~ msgstr "Bilder exportieren" +#~ msgid "Extension already exits" +#~ msgstr "Erweiterung existiert bereits" +#~ msgid "Extension is empty" +#~ msgstr "Erweiterung ist leer" +#~ msgid "" +#~ "Extensions supported:\n" +#~ "SIZE\n" +#~ "PASV\n" +#~ "REST\n" +#~ "End of extentions." +#~ msgstr "" +#~ "Unterstützte Erweiterungen:\n" +#~ "SIZE\n" +#~ "PASV\n" +#~ "REST\n" +#~ "Ende der Erweiterungen." +#~ msgid "Extra Headers Text Editor" +#~ msgstr "Texteditor für Extra-Header" +#~ msgid "F&ind First" +#~ msgstr "&Ersten suchen" +#~ msgid "FTP daemon" +#~ msgstr "FTP-Daemon" +#~ msgid "Facets and Enumeration not allowed on this kind of datatype \"%s\"" +#~ msgstr "Facetten und Enumeration für diesen Datentyp \"%s\" nicht zulässig" +#~ msgid "Fahrenheit" +#~ msgstr "Fahrenheit" +#~ msgid "Failed attempting to retrieve time zone information." +#~ msgstr "" +#~ "Das Einlesen der Informationen über die Zeitzone ist fehlgeschlagen." +#~ msgid "Failed to Start: %s" +#~ msgstr "Start fehlgeschlagen: %s" +#~ msgid "Failed to Stop: %s" +#~ msgstr "Anhalten fehlgeschlagen: %s" +#~ msgid "" +#~ "Fatal error: Cannot create application object in a shared object or " +#~ "library." +#~ msgstr "" +#~ "Fataler Fehler: Ein Anwendungsobjekt kann nicht in einem Shared Object " +#~ "oder einer Bibliothek erzeugt werden." +#~ msgid "Fatal error: Cannot create more than one TApplication instance" +#~ msgstr "" +#~ "Fataler Fehler: Mehr als eine Instanz von TApplication kann nicht erzeugt " +#~ "werden" +#~ msgid "Fathoms" +#~ msgstr "Faden" +#~ msgid "Feet" +#~ msgstr "Fuß" +#~ msgid "Fetch &Params" +#~ msgstr "&Parameter holen" +#~ msgid "Fi&nd what:" +#~ msgstr "&Suchen nach:" +#~ msgid "Field %s changed by another user" +#~ msgstr "Feld %s wurde von einem anderen Benutzer geändert" +#~ msgid "Field %s did not provide an image" +#~ msgstr "Feld %s enthielt kein Bild" +#~ msgid "Field %s requires a value" +#~ msgstr "Für Feld %s ist ein Wert erforderlich" +#~ msgid "Field not found: %s" +#~ msgstr "Feld nicht gefunden: %s" +#~ msgid "Field view not permitted" +#~ msgstr "Feldansicht nicht zulässig" +#~ msgid "Fieldname %s exceeds %d chars" +#~ msgstr "Feldname %s überschreitet %d Zeichen" +#~ msgid "File" +#~ msgstr "Datei" +#~ msgid "File \"%s\" not found" +#~ msgstr "Datei \"%s\" konnte nicht gefunden werden" +#~ msgid "File Status:" +#~ msgstr "Dateistatus:" +#~ msgid "File Type:" +#~ msgstr "Dateityp:" +#~ msgid "File include error on line %d: expecting \"" +#~ msgstr "include-Dateifehler auf Zeile %d: erwartet \"" +#~ msgid "File include error on line %d: expecting =" +#~ msgstr "include-Dateifehler auf Zeile %d: erwartet =" +#~ msgid "" +#~ "File include error on line %d: expecting virtual, file, or page, but " +#~ "found %s." +#~ msgstr "" +#~ "include-Dateifehler auf Zeile %d: erwaret virtual, Datei, oder Seite, " +#~ "aber %s gefunden." +#~ msgid "File name too long." +#~ msgstr "Dateiname ist zu lang." +#~ msgid "File status okay; about to open data connection." +#~ msgstr "Dateistatus OK; Datenverbindung wird geöffnet." +#~ msgid "FileName cannot be blank" +#~ msgstr "FileName muss angegeben werden" +#~ msgid "FileName property cannot be blank" +#~ msgstr "Eigenschaft FileName darf nicht leer sein" +#~ msgid "Filename(s)" +#~ msgstr "Dateiname(n)" +#~ msgid "Find" +#~ msgstr "Suchen" +#~ msgid "Find &Next" +#~ msgstr "&Weitersuchen" +#~ msgid "Find First|Finds the first occurance of specified text" +#~ msgstr "Suchen" +#~ msgid "Find Next|Repeats the last find" +#~ msgstr "Weitersuchen|Letzte Suche wiederholen" +#~ msgid "Find|Finds the specified text" +#~ msgstr "Suchen|Angegebenen Text suchen" +#~ msgid "FluidCups" +#~ msgstr "Tasse (Flüssigkeit)" +#~ msgid "FluidGallons" +#~ msgstr "Gallone (Flüssigkeit)" +#~ msgid "FluidGills" +#~ msgstr "Gill (Flüssigkeit)" +#~ msgid "FluidOunces" +#~ msgstr "Unze (Flüssigkeit)" +#~ msgid "FluidPints" +#~ msgstr "Pinte (Flüssigkeit)" +#~ msgid "FluidQuarts" +#~ msgstr "Quart (Flüssigkeit)" +#~ msgid "FluidTablespoons" +#~ msgstr "Esslöffel (Flüssigkeit)" +#~ msgid "FluidTeaspoons" +#~ msgstr "Teelöffel (Flüssigkeit)" +#~ msgid "Font Select" +#~ msgstr "MS Sans Serif" +#~ msgid "For the latest updates and information please visit:" +#~ msgstr "Die neuesten Aktualisierungen und Informationen finden Sie unter:" +#~ msgid "Forbidden" +#~ msgstr "Verboten" +#~ msgid "Format" +#~ msgstr "Format" +#~ msgid "Fortnights" +#~ msgstr "Vierzehn Tage" +#~ msgid "Forward" +#~ msgstr "Weiter" +#~ msgid "Found" +#~ msgstr "Gefunden" +#~ msgid "Free Space" +#~ msgstr "Freier Speicherplatz" +#~ msgid "Fuchsia" +#~ msgstr "Fuchsie" +#~ msgid "Furlongs" +#~ msgstr "Achtelmeile" +#~ msgid "Gateway timeout" +#~ msgstr "Zeitüberschreitung bei Gateway" +#~ msgid "General SOCKS server failure." +#~ msgstr "Allgemeiner SOCKS-Serverausfall." +#~ msgid "Getting the Count of a TComponentsEnumerator object is not supported" +#~ msgstr "" +#~ "Das Lesen von Count eines TComponentsEnumerator-Objekts wiurd nicht " +#~ "unterstützt" +#~ msgid "Gigameters" +#~ msgstr "Gigameter" +#~ msgid "Global scheam items may not contain a ref" +#~ msgstr "Globale Schemaelemente dürfen keine Verweise enthalten" +#~ msgid "Go" +#~ msgstr "Start" +#~ msgid "Gone" +#~ msgstr "Fort" +#~ msgid "Goodbye" +#~ msgstr "Auf Wiedersehen" +#~ msgid "Gradient Active Caption" +#~ msgstr "Gradient aktiver Titel" +#~ msgid "Gradient Inactive Caption" +#~ msgstr "Gradient inaktiver Titel" +#~ msgid "Grains" +#~ msgstr "Gran" +#~ msgid "Grams" +#~ msgstr "Gramm" +#~ msgid "Gray" +#~ msgstr "Grau" +#~ msgid "Gray Text" +#~ msgstr "Grauer Text" +#~ msgid "Green" +#~ msgstr "Grün" +#~ msgid "Group" +#~ msgstr "Gruppe" +#~ msgid "HTTP version not supported" +#~ msgstr "HTTP-Version nicht unterstützt" +#~ msgid "Hands" +#~ msgstr "Handbreite" +#~ msgid "Header Section owner must be a TCustomHeaderControl" +#~ msgstr "" +#~ "Der Besitzer des Header-Abschnitts muss ein TCustomHeaderControl sein" +#~ msgid "Header has already been written." +#~ msgstr "Der Header wurde bereits geschrieben." +#~ msgid "Hectares" +#~ msgstr "Hektoar" +#~ msgid "HectoLiters" +#~ msgstr "Hektoliter" +#~ msgid "Hectograms" +#~ msgstr "Hektogramm" +#~ msgid "Hectometers" +#~ msgstr "Hektometer" +#~ msgid "Hello %s" +#~ msgstr "Hallo %s" +#~ msgid "Help Contents" +#~ msgstr "Inhalt der Hilfe" +#~ msgid "Help on help" +#~ msgstr "Verwendung der Hilfe" +#~ msgid "Hidden User: Information was not returned at a user's request" +#~ msgstr "" +#~ "Verborgener Benutzer: Information wurde nicht auf Anforderung des " +#~ "Benutzers zurückgeschickt" +#~ msgid "Highlight Background" +#~ msgstr "Hervorgehobener Hintergrund" +#~ msgid "Highlight Text" +#~ msgstr "Hervorgehobener Text" +#~ msgid "Ho&me" +#~ msgstr "&Start" +#~ msgid "Home directory" +#~ msgstr "Startverzeichnis" +#~ msgid "Host field is empty" +#~ msgstr "Host-Feld ist leer" +#~ msgid "Host is down." +#~ msgstr "Der Host ist ausgefallen." +#~ msgid "Host is empty" +#~ msgstr "Host ist leer" +#~ msgid "Host not found." +#~ msgstr "Host nicht gefunden." +#~ msgid "Host unreachable." +#~ msgstr "Host nicht erreichbar." +#~ msgid "Hour Offset portion of time invalid" +#~ msgstr "Der Stunden-Offset des Zeitwertes ist ungültig" +#~ msgid "Hours" +#~ msgstr "Stunde" +#~ msgid "Html files (*.htm *.html)|*.htm;*.html" +#~ msgstr "Html-Dateien (*.htm;*.html)|*.htm;*.html" +#~ msgid "Html files (*.htm;*.html)|*.htm;*.html" +#~ msgstr "Html-Dateien (*.htm;*.html)|*.htm;*.html" +#~ msgid "I&mage Index:" +#~ msgstr "Bild-Inde&x:" +#~ msgid "ICMP Receive Error = 0." +#~ msgstr "ICMP Receive Error = 0." +#~ msgid "IDOMNode required" +#~ msgstr "IDOMNode erforderlich" +#~ msgid "IOHandler value is not valid" +#~ msgstr "Wert für IOHandler ist ungültig" +#~ msgid "IRC Connect Failed" +#~ msgstr "IRC-Verbindung fehlgeschlagen" +#~ msgid "IconView Items Editor" +#~ msgstr "IconView-Eintragseditor" +#~ msgid "Illegal family" +#~ msgstr "Ungültige Familie" +#~ msgid "Illegal type" +#~ msgstr "Ungültiger Typ" +#~ msgid "Ima&ge Index:" +#~ msgstr "&Bildindex:" +#~ msgid "Image format not recognized" +#~ msgstr "Das Grafikformat wurde nicht erkannt" +#~ msgid "Image width and heigth must match" +#~ msgstr "Die Höhe muss mit der Breite der Grafik übereinstimmen" +#~ msgid "ImageList Editor" +#~ msgstr "Bilderlisteneditor" +#~ msgid "Inactive Border" +#~ msgstr "Inaktiver Rahmen" +#~ msgid "Inactive Caption" +#~ msgstr "Inaktiver Titel" +#~ msgid "Inactive Caption Text" +#~ msgstr "Inaktiver Titeltext" +#~ msgid "Inches" +#~ msgstr "Zoll" +#~ msgid "Include file %s includes itself" +#~ msgstr "Include-Datei %s verweist auf sich selbst" +#~ msgid "Incompatible conversion types [%s - %s, %s - %s]" +#~ msgstr "Inkompatible Konvertierungstypen [%s - %s, %s - %s]" +#~ msgid "Incompatible conversion types [%s, %s, %s]" +#~ msgstr "Inkompatible Konvertierungstypen [%s, %s, %s]" +#~ msgid "Incompatible conversion types [%s, %s]" +#~ msgstr "Inkompatible Konvertierungstypen [%s, %s]" +#~ msgid "Incorrect image format (%0:s) for field %1:s" +#~ msgstr "Falsches Image-Format (%0:s) für Feld %1:s" +#~ msgid "Incorrect length in received block" +#~ msgstr "Falsche Länge in empfangenem Block" +#~ msgid "Increment By" +#~ msgstr "Erhöhen um" +#~ msgid "Indy Clients" +#~ msgstr "Indy-Clients" +#~ msgid "Indy FTP Server ready." +#~ msgstr "Indy FTP-Server bereit." +#~ msgid "Indy I/O Handlers" +#~ msgstr "Indy-I/O-Handler" +#~ msgid "Indy Intercepts" +#~ msgstr "Indy-Intercepts" +#~ msgid "Indy Misc" +#~ msgstr "Indy-Misc" +#~ msgid "Indy SMTP Server" +#~ msgstr "Indy SMTP-Server" +#~ msgid "Indy Servers" +#~ msgstr "Indy-Server" +#~ msgid "Indy Telnet Server" +#~ msgstr "Indy Telnet-Server" +#~ msgid "Info Background" +#~ msgstr "Info-Hintergrund" +#~ msgid "Info Text" +#~ msgstr "Info-Text" +#~ msgid "Informational: informational messages" +#~ msgstr "Informational: Informationsbotschaften" +#~ msgid "" +#~ "Initialization of script debugger failed. Verify that a script debugger " +#~ "is installed" +#~ msgstr "" +#~ "Initialisierung des Script-Debugger ist misslungen. Überprüfen Sie, ob " +#~ "ein Script-Debugger installiert ist." +#~ msgid "Inserted" +#~ msgstr "Eingefügt" +#~ msgid "Insufficient data for Content-Length" +#~ msgstr "Nicht ausreichnede Daten für Inhaltslänge" +#~ msgid "Integer parameter expected" +#~ msgstr "Integer-Parameter erwartet" +#~ msgid "" +#~ "InterBase library gds.so.0 not found in the path. Please install " +#~ "InterBase to use this functionality" +#~ msgstr "" +#~ "InterBase-Bibliothek gds.so.0 im Pfad nicht gefunden. Bitte installieren " +#~ "Sie InterBase für diese Funktion" +#~ msgid "InterbaseExpress %g" +#~ msgstr "InterbaseExpress %g" +#~ msgid "InterbaseExpress 4.3" +#~ msgstr "InterbaseExpress 4.3" +#~ msgid "InterceptEnabled cannot be set to true when Intercept is nil." +#~ msgstr "" +#~ "InterceptEnabled darf nicht auf true gesetzt sein, wenn Intercept nil ist." +#~ msgid "Interface %s has no RTTI" +#~ msgstr "Schnittstelle %s hat kein RTTI" +#~ msgid "" +#~ "Interface (%s) canno be remoted - please verify the interface declaration " +#~ "- specially the methods calling convention!" +#~ msgstr "" +#~ "Interface (%s) kann nicht ausgelagert werden - überprüfen Sie die " +#~ "Interface-Deklaration - speziell die Aufrufkonventionen der Methoden!" +#~ msgid "" +#~ "Interface (%s) is not registered - please include the unit that registers " +#~ "this interface to your project" +#~ msgstr "" +#~ "Interface (%s) ist nicht registriert - fügen Sie die Unit, die dieses " +#~ "Interface registriert, in Ihr Projekt ein" +#~ msgid "Interface has no RTTI, UUID = %s" +#~ msgstr "Schnittstelle hat kein RTTI, UUID = %s" +#~ msgid "Interface is unusable due to failure to stop" +#~ msgstr "Interface ist unbrauchbar, da es nicht angehalten werden kann" +#~ msgid "Interface not registered, UUID = %s" +#~ msgstr "Schnittstelle nicht registriert, UUID = %s" +#~ msgid "Interface was already started" +#~ msgstr "Interface wurde bereits gestartet" +#~ msgid "Interface was already stopped" +#~ msgstr "Interface wurde bereits angehalten" +#~ msgid "Internal Server Error" +#~ msgstr "Interner Server-Fehler" +#~ msgid "Internal error: data type kind %s not expected in this context" +#~ msgstr "Interner Fehler: Datentyp %s in diesem Kontext nicht erwartet" +#~ msgid "Internet" +#~ msgstr "Internet" +#~ msgid "Internet Direct (Indy)" +#~ msgstr "Internet Direct (Indy)" +#~ msgid "Interpretation of message failed" +#~ msgstr "Die Interpretation der Botschaft ist nicht gelungen" +#~ msgid "Interrupted system call." +#~ msgstr "Unterbrochener Systemaufruf." +#~ msgid "Invalid %s value: \"%s\"" +#~ msgstr "Ungültiger %s-Wert: \"%s\"" +#~ msgid "Invalid Action %d" +#~ msgstr "Ungültige Aktion %d" +#~ msgid "Invalid Bcd Precision (%d) or Scale (%d)" +#~ msgstr "Ungültige Bcd-Genauigkeit (%d) oder -Skalierung (%d)" +#~ msgid "" +#~ "Invalid Colormap this ActionBand requires ColorMaps of type " +#~ "TCustomActionBarColorMapEx" +#~ msgstr "" +#~ "Ungültige Colormap. Dieses ActionBand benötigt ColorMaps des Typ " +#~ "TCustomActionBarColorMapEx" +#~ msgid "Invalid DOMString size" +#~ msgstr "Fehler bei DOMString-Größe" +#~ msgid "Invalid DispID for parameter %d in method %s" +#~ msgstr "Ungültige DispID für Parameter %d in Methode %s" +#~ msgid "Invalid Encoding. UU only allows Body and Attachments" +#~ msgstr "Ungültige Codierung. UU gestattet nur Rumpf und Anlage" +#~ msgid "Invalid HTML encoded character (%s) at position %d" +#~ msgstr "Ungültiges HTML-codiertes Zeichen (%s) an Position %d" +#~ msgid "Invalid HTTP Request: Length is 0" +#~ msgstr "Ungültige HTTP-Anforderung: Länge ist 0" +#~ msgid "Invalid HTTP Response: Length is 0" +#~ msgstr "Ungültige HTTP-Antwort: Länge ist 0" +#~ msgid "Invalid Header Id %d" +#~ msgstr "Ungültige Header-Id %d" +#~ msgid "Invalid LCDNumber value" +#~ msgstr "Ungültiger Wert für LCDNumber" +#~ msgid "Invalid Login." +#~ msgstr "Ungültige Anmeldung." +#~ msgid "Invalid MDIParent for class %s" +#~ msgstr "Ungültiger MDIParent für Klasse %s" +#~ msgid "Invalid NULL variant operation" +#~ msgstr "Ungültige NULL-Variant-Operation" +#~ msgid "Invalid Packet Size %d" +#~ msgstr "Ungültige Paketgröße %d" +#~ msgid "Invalid Pointer" +#~ msgstr "Ungültiger Zeiger" +#~ msgid "Invalid Port Range (%d - %d)" +#~ msgstr "Ungültiger Port-Bereich (%d - %d)" +#~ msgid "" +#~ "Invalid Port: The foreign or local port is not specified correctly or " +#~ "invalid" +#~ msgstr "" +#~ "Ungültiger Port: Der fremde oder lokale Port ist nicht korrekt angegeben " +#~ "oder ungültig" +#~ msgid "Invalid Query Count %d" +#~ msgstr "Ungültige Abfragezahl %d" +#~ msgid "Invalid SOAP Response" +#~ msgstr "Ungültige SOAP-Antwort" +#~ msgid "Invalid SOAP array specification" +#~ msgstr "Ungültige SOAP-Array-Festlegung" +#~ msgid "Invalid SOAP request" +#~ msgstr "Ungültige SOAP-Anforderung" +#~ msgid "Invalid SOAP response" +#~ msgstr "Ungültige SOAP-Antwort" +#~ msgid "Invalid SQL date/time values" +#~ msgstr "Ungültige SQL-Datums-/Uhrzeitwerte" +#~ msgid "Invalid Syslog message: packet too large (%d bytes)" +#~ msgstr "Ungültige syslog-Botschaft: Paket zu groß (%d Byte)" +#~ msgid "Invalid Text count. TIdText must be greater than 1" +#~ msgstr "Ungültige Anzahl für Text. TIdText muss größer als 1 sein" +#~ msgid "Invalid URL encoded character (%s) at position %d" +#~ msgstr "Ungültiger URL-codiertes Zeichen (%s) bei Position %d" +#~ msgid "" +#~ "Invalid WSDL document '%s' - Please verify the location and content!\n" +#~ "Error: %s" +#~ msgstr "" +#~ "Ungültiges WSDL-Dokument '%s' - Bitte überprüfen Sie Speicherort und " +#~ "Inhalt!\n" +#~ "Fehler: %s" +#~ msgid "Invalid XImage" +#~ msgstr "Ungültiges XImage" +#~ msgid "Invalid access" +#~ msgstr "Ungültiger Zugriff" +#~ msgid "Invalid argument" +#~ msgstr "Ungültiges Argument" +#~ msgid "Invalid argument." +#~ msgstr "Ungültiges Argument." +#~ msgid "Invalid built-in type name \"%s\"" +#~ msgstr "Ungültiger Name für integrierten Typ \"%s\"" +#~ msgid "Invalid canvas state request" +#~ msgstr "Ungültige Status-Anforderung für Canvas" +#~ msgid "Invalid character in name" +#~ msgstr "Ungültiges Zeichen im Namen" +#~ msgid "Invalid complex type derivation: %s" +#~ msgstr "Ungültige Ableitung des komplexen Typs: %s" +#~ msgid "Invalid date string: %s" +#~ msgstr "Ungültiger Datums-String: %s" +#~ msgid "Invalid day: %d" +#~ msgstr "Ungültiger Tag: %d" +#~ msgid "Invalid decimal string: ''%s''" +#~ msgstr "Ungültiger Dezimal-String: ''%s''" +#~ msgid "Invalid duration string: %s" +#~ msgstr "Ungültiger Zeitdauer-String: %s" +#~ msgid "Invalid format type for BCD" +#~ msgstr "Ungültiger Formattyp für BCD" +#~ msgid "Invalid fractional second: %f" +#~ msgstr "Ungültiger Sekundenbruchteil: %f" +#~ msgid "Invalid graphic format" +#~ msgstr "Ungültiges Grafikformat" +#~ msgid "Invalid group declaration in \"%s\"" +#~ msgstr "Ungültige Gruppendeklaration in \"%s\"" +#~ msgid "Invalid handle value for %s" +#~ msgstr "Ungültiger Handle-Wert für %s" +#~ msgid "" +#~ "Invalid host name. A SYSLOG host name cannot contain any space (\"%s\")+" +#~ msgstr "" +#~ "Ungültiger Host-Name. Ein SYSLOG Host-Name darf keine Leerzeichen " +#~ "enthalten(\"%s\")+" +#~ msgid "Invalid hour offset: %d" +#~ msgstr "Ungültiger Stunden-Offset: %d" +#~ msgid "Invalid hour: %d" +#~ msgstr "Ungültige Stunde: %d" +#~ msgid "Invalid image" +#~ msgstr "Ungültiges Bild" +#~ msgid "Invalid image (the size is less than 4 bytes long)." +#~ msgstr "Ungültige Grafik (die Größe ist geringer als 4 Byte)." +#~ msgid "Invalid image dimension" +#~ msgstr "Ungültige Grafikdimension" +#~ msgid "Invalid image type" +#~ msgstr "Ungültiger Grafiktyp" +#~ msgid "Invalid millisecond: %d" +#~ msgstr "Ungültige Millisekunde: %d" +#~ msgid "Invalid minute: %d" +#~ msgstr "Ungültige Minute: %d" +#~ msgid "Invalid modification" +#~ msgstr "Ungültige Änderung" +#~ msgid "Invalid month: %d" +#~ msgstr "Ungültiger Monat: %d" +#~ msgid "Invalid namespace request" +#~ msgstr "Ungültige Namespace-Anforderung" +#~ msgid "Invalid network mask." +#~ msgstr "Ungültige Netzwerkmaske." +#~ msgid "Invalid node type" +#~ msgstr "Ungültiger Knotentyp" +#~ msgid "Invalid operation on a hosted node" +#~ msgstr "Ungültige Operation für einen hosted-Knoten" +#~ msgid "Invalid option specified" +#~ msgstr "Ungültige Option angegeben" +#~ msgid "Invalid or Unknown Time Zone" +#~ msgstr "Ungültige oder unbekannte Zeitzone" +#~ msgid "Invalid or unsupported XML Schema document" +#~ msgstr "Ungültiges oder nicht unterstütztes XML-Schemadokument" +#~ msgid "Invalid parent class: %s" +#~ msgstr "Ungültige übergeordnete Klasse: %s" +#~ msgid "Invalid password" +#~ msgstr "Ungültiges Passwort" +#~ msgid "Invalid second: %d" +#~ msgstr "Ungültige Sekunde: %d" +#~ msgid "Invalid second: %f" +#~ msgstr "Ungültige Sekunde: %f" +#~ msgid "Invalid socks authentication method." +#~ msgstr "Ungültige Authentifizierungmethode für SOCKS." +#~ msgid "Invalid state" +#~ msgstr "Ungültiger Status" +#~ msgid "Invalid stream operation" +#~ msgstr "Ungültige Stream-Operation" +#~ msgid "Invalid string offset" +#~ msgstr "Ungültiger String-Offset" +#~ msgid "Invalid syntax" +#~ msgstr "Syntaxfehler" +#~ msgid "Invalid syslog message: incorrect PRI number \"%s\"" +#~ msgstr "Ungültige syslog-Botschaft: Nicht korrekte PRI-Nummer \"%s\"" +#~ msgid "Invalid syslog message: incorrect PRI section" +#~ msgstr "Ungültige syslog-Botschaft: Nicht korrekter PRI-Abschnitt" +#~ msgid "Invalid syslog message: incorrect timestamp \"%s\"" +#~ msgstr "Ungültige syslog-Botschaft: Ungültiger Zeitstempel \"%s\"" +#~ msgid "Invalid time string: %s" +#~ msgstr "Ungültiger Zeit-String: %s" +#~ msgid "Invalid url '%s' - only supports 'http' and 'https' schemes" +#~ msgstr "Ungültige URL '%s' - unterstützt nur Schemata 'http' und 'https'" +#~ msgid "Invalid value length: Should be 32." +#~ msgstr "Ungültige Länge von Wert: sollte 32 sein." +#~ msgid "Invalid variant operation ($%.8x)" +#~ msgstr "Ungültige Variant-Operation ($%.8x)" +#~ msgid "" +#~ "Invalid variant operation (%s%.8x)\n" +#~ "%s" +#~ msgstr "" +#~ "Ungültige Variant-Operation (%s%.8x)\n" +#~ "%s" +#~ msgid "Invalid variant type" +#~ msgstr "Ungültiger Variant-Typ" +#~ msgid "Invalid widget handle" +#~ msgstr "Ungültiges Widget-Handle" +#~ msgid "Invokable Class %s implements no interfaces" +#~ msgstr "Aufrufbare Klasse %s implementiert keine Schnittstellen" +#~ msgid "Item %s has subitems, delete anyway?" +#~ msgstr "Element %s hat Unterelemente, trotzdem löschen?" +#~ msgid "Item %s is not allowed to be moved" +#~ msgstr "Eintrag %s darf nicht verschoben werden" +#~ msgid "Item Properties" +#~ msgstr "Eigens&chaften des Eintrags" +#~ msgid "Item not found ($0%x)" +#~ msgstr "Eintrag nicht gefunden ($0%x)" +#~ msgid "ItemTag property is not initialized" +#~ msgstr "Die Eigenschaft ItemTag ist nicht initialisiert" +#~ msgid "Items Editor..." +#~ msgstr "Eintrags-Editor..." +#~ msgid "Jpegs" +#~ msgstr "Jpegs" +#~ msgid "JulianDate" +#~ msgstr "Julianisches Datum" +#~ msgid "Kelvin" +#~ msgstr "Kelvin" +#~ msgid "Key" +#~ msgstr "Schlüssel" +#~ msgid "Key \"%s\" not found" +#~ msgstr "Taste \"%s\" nicht gefunden" +#~ msgid "Key may not contain equals sign (\"=\")" +#~ msgstr "Schlüssel darf keine Gleichheitszeichen (\"=\") enthalten" +#~ msgid "KiloLiters" +#~ msgstr "Kiloliter" +#~ msgid "Kilograms" +#~ msgstr "Kilogramm" +#~ msgid "Kilometers" +#~ msgstr "Kilometer" +#~ msgid "L&oad" +#~ msgstr "L&aden" +#~ msgid "L&og" +#~ msgstr "Pr&otokoll" +#~ msgid "Large &Icons" +#~ msgstr "&Große Symbole" +#~ msgid "Large icon view" +#~ msgstr "Große Symbole anzeigen" +#~ msgid "Last Response Time:" +#~ msgstr "Letzte Antwortzeit:" +#~ msgid "Length Required" +#~ msgstr "Länge benötigt" +#~ msgid "LightYears" +#~ msgstr "Lichtjahr" +#~ msgid "Lime" +#~ msgstr "Limone" +#~ msgid "Line" +#~ msgstr "Linie" +#~ msgid "Link to " +#~ msgstr "Verknüpfung auf " +#~ msgid "Links" +#~ msgstr "Link" +#~ msgid "List" +#~ msgstr "Liste" +#~ msgid "List is locked during an active ForEach" +#~ msgstr "Liste ist während eines aktiven ForEach gesperrt" +#~ msgid "List view" +#~ msgstr "Listenansicht" +#~ msgid "ListButton" +#~ msgstr "ListButton" +#~ msgid "ListView Items Editor" +#~ msgstr "ListView-Eintragseditor" +#~ msgid "Listbox (%s) style must be virtual in order to set Count" +#~ msgstr "" +#~ "Stil des Listenfeldes (%s) muss virtuell sein, damit Count gesetzt werden " +#~ "kann" +#~ msgid "Lists all the PortTypes published by this Service" +#~ msgstr "Listet alle PortTypes, die von diesem Service publiziert werden" +#~ msgid "Liters" +#~ msgstr "Liter" +#~ msgid "Lo&gin Prompt" +#~ msgstr "A&nmeldeaufforderung" +#~ msgid "Load Picture" +#~ msgstr "Bild laden" +#~ msgid "Loading..." +#~ msgstr "Laden..." +#~ msgid "Local time is %s" +#~ msgstr "Ortszeit ist %s" +#~ msgid "Local type declarations cannot have a name. Element: %s" +#~ msgstr "Lokale Typdeklarationen dürfen keinen Namen besitzen. Element: %s" +#~ msgid "Log files (*.log)" +#~ msgstr "Protokolldateien (*.log)" +#~ msgid "Log(%d)" +#~ msgstr "Log(%d)" +#~ msgid "LogDetail" +#~ msgstr "LogDetail" +#~ msgid "Login page is not defined" +#~ msgstr "Login-Seite ist nicht definiert" +#~ msgid "Login with USER first." +#~ msgstr "Zuerst anmelden mit USER." +#~ msgid "LongTons" +#~ msgstr "Tonne (UK)" +#~ msgid "MD is an Obsolete Command. Use MX." +#~ msgstr "MD ist eine veraltete Anweisung. Verwenden Sie MX." +#~ msgid "MF is an Obsolete Command. USE MX." +#~ msgstr "MFist eine veraltete Anweisung. Verwenden Sie MX." +#~ msgid "Ma&x Events:" +#~ msgstr "Ma&x. Ereignisse:" +#~ msgid "MailA is an Obsolete Command. USE MX." +#~ msgstr "MailA ist eine veraltete Anweisung. Verwenden Sie MX." +#~ msgid "MainUpdateAction" +#~ msgstr "MainUpdateAction" +#~ msgid "Maroon" +#~ msgstr "Braun" +#~ msgid "Mass" +#~ msgstr "Masse" +#~ msgid "Match &case" +#~ msgstr "Groß-/&Kleinschreibung" +#~ msgid "Match &whole word only" +#~ msgstr "&Nur ganze Wörter" +#~ msgid "Max Response Time:" +#~ msgstr "Max. Antwortzeit:" +#~ msgid "Max line length exceeded." +#~ msgstr "Max. Zeilenlänge überschritten." +#~ msgid "Maximum connections limit exceeded. Try again later." +#~ msgstr "Max. Anzahl an Verbindungen überschritten. Versuchen Sie es später." +#~ msgid "Maximum sessions exceeded" +#~ msgstr "Maximale Sitzungsanzahl überschritten" +#~ msgid "Me&nu show recently used items first" +#~ msgstr "Optionen" +#~ msgid "Medium Gray" +#~ msgstr "Mittelgrau" +#~ msgid "Megameters" +#~ msgstr "Megameter" +#~ msgid "Menu Background" +#~ msgstr "Menühintergrund" +#~ msgid "Menu Text" +#~ msgstr "Menütext" +#~ msgid "Menu insertion recursion not allowed" +#~ msgstr "Rekursion beim Einfügen von Menüs ist nicht gestattet" +#~ msgid "Merge" +#~ msgstr "Zusammenführen" +#~ msgid "Message decoder not found" +#~ msgstr "Botschafts-Decoder nicht gefunden" +#~ msgid "Message encoder not found" +#~ msgstr "Botschafts-Encoder nicht gefunden" +#~ msgid "Message handling failed" +#~ msgstr "Botschaftsbehandlung fehlgeschlagen" +#~ msgid "Message too long." +#~ msgstr "Die Botschaft ist zu lang." +#~ msgid "Message type recognition error" +#~ msgstr "Fehler beim Erkennen des Botschaftentyps" +#~ msgid "Meters" +#~ msgstr "Meter" +#~ msgid "Method %s of class %s not found" +#~ msgstr "Methode %s aus Klasse %s nicht gefunden" +#~ msgid "Method definition for %s has over %d parameters" +#~ msgstr "Methodendefinition für %s hat mehr als %d Parameter" +#~ msgid "Method has no RTTI" +#~ msgstr "Methode hat kein RTTI" +#~ msgid "Method not allowed" +#~ msgstr "Methode nicht erlaubt" +#~ msgid "Method not permitted in TSoapDataList" +#~ msgstr "Methode nicht erlaubt in TSoapDataList" +#~ msgid "MetricTons" +#~ msgstr "Metrische Tonne" +#~ msgid "Micrograms" +#~ msgstr "Mikrogramm" +#~ msgid "Micromicrons" +#~ msgstr "Mikromikron" +#~ msgid "Microns" +#~ msgstr "Mikron" +#~ msgid "Microsoft MSXML is not installed" +#~ msgstr "Microsoft MSXML ist nicht installiert" +#~ msgid "Miles" +#~ msgstr "Meile" +#~ msgid "Millennia" +#~ msgstr "Jahrtausend" +#~ msgid "MilliLiters" +#~ msgstr "Milliliter" +#~ msgid "MilliSeconds" +#~ msgstr "Millisekunde" +#~ msgid "Milligrams" +#~ msgstr "Milligramm" +#~ msgid "Millimeters" +#~ msgstr "Millimeter" +#~ msgid "Millimicrons" +#~ msgstr "Millimikron" +#~ msgid "Millisecond Values must be between 000 - 999" +#~ msgstr "Werte für Milliskeunden müssen zwischen 000 - 999 liegen" +#~ msgid "Mime format not supported for TIcon" +#~ msgstr "Mime-Format wird für TIcon nicht unterstützt" +#~ msgid "MimeSource format must have an associated data stream" +#~ msgstr "Dem MimeSource-Format muss ein Daten-Stream zugeordnet sein" +#~ msgid "Mimetype is empty" +#~ msgstr "Mimetype ist leer" +#~ msgid "Min Response Time:" +#~ msgstr "Min. Antwortzeit:" +#~ msgid "Minimize All" +#~ msgstr "Alle verkleinern" +#~ msgid "Minutes" +#~ msgstr "Minute" +#~ msgid "Mismatched paramaters to RegisterChildNodes" +#~ msgstr "Nicht übereinstimmende Parameter bei RegisterChildNodes" +#~ msgid "Missing Database property" +#~ msgstr "Eigenschaft Database fehlt" +#~ msgid "Missing DriverName property" +#~ msgstr "Eigenschaft DriverName fehlt" +#~ msgid "Missing FaultString or FaultCode element" +#~ msgstr "Fehlendes FaultString- oder FaultCode-Element" +#~ msgid "Missing ProgID" +#~ msgstr "Fehlende ProgID" +#~ msgid "Missing SQLConnection property" +#~ msgstr "Eigenschaft SQLConnection fehlt" +#~ msgid "Missing Type name" +#~ msgstr "Typname fehlt" +#~ msgid "Missing XML Data Component" +#~ msgstr "XML-Datenkomponente fehlt" +#~ msgid "Missing password" +#~ msgstr "Passwort fehlt" +#~ msgid "Missing query, table name or procedure name" +#~ msgstr "Fehlende Abfrage, Tabellen- oder Prozedurname" +#~ msgid "Missing user name" +#~ msgstr "Benutzername fehlt" +#~ msgid "Mode has not been set." +#~ msgstr "Der Modus wurde nicht gesetzt." +#~ msgid "Mode is not initialised" +#~ msgstr "Modus ist nicht initialisiert" +#~ msgid "Mode set to %s." +#~ msgstr "Modus ist gesetzt auf %s." +#~ msgid "Modification of %s is not permitted" +#~ msgstr "Modifikation von %s nicht zulässig" +#~ msgid "Modified" +#~ msgstr "Geändert" +#~ msgid "ModifiedJulianDate" +#~ msgstr "Modifiziertes julianisches Datum" +#~ msgid "Money Green" +#~ msgstr "Dollargrün" +#~ msgid "Months" +#~ msgstr "Monat" +#~ msgid "More Buttons" +#~ msgstr "Weitere Schaltflächen" +#~ msgid "Move Selection" +#~ msgstr "Liste" +#~ msgid "Moved Permanently" +#~ msgstr "Permanent verschoben" +#~ msgid "Moved Temporarily" +#~ msgstr "Temporär verschoben" +#~ msgid "Movie not loaded" +#~ msgstr "Film nicht geladen" +#~ msgid "Multiple Connections not supported by %s driver" +#~ msgstr "Mehrfach-Verbindungen werden vom %s-Treiber nicht unterstützt" +#~ msgid "Multiple body elements not supported" +#~ msgstr "Mehrere Rumpfelemente werden nicht unterstützt" +#~ msgid "Multiselect mode must be on for this feature" +#~ msgstr "Mehrfachauswahl muss für diese Funktion aktiviert sein" +#~ msgid "" +#~ "Must enable multiref output for objects when serializing a graph of " +#~ "objects - (%s)" +#~ msgstr "" +#~ "Multiref-Output für Objekte muss aktviert werden bei der Serialisierung " +#~ "eines Objektdiagramms - (%s)" +#~ msgid "Must have a target stream" +#~ msgstr "Ziel-Stream muss vorhanden sein" +#~ msgid "N&ew SubItem" +#~ msgstr "Neuer &Untereintrag" +#~ msgid "N&ew SubNode" +#~ msgstr "Neuer Unter&knoten" +#~ msgid "NTP subsystem" +#~ msgstr "NTP-Subsystem" +#~ msgid "Name not allowed on a ref item" +#~ msgstr "Name für Verweiselement nicht zulässig" +#~ msgid "Namespace URI" +#~ msgstr "Namespace-URI" +#~ msgid "Nanograms" +#~ msgstr "Nanogramm" +#~ msgid "NauticalMiles" +#~ msgstr "Seemeile" +#~ msgid "Navy" +#~ msgstr "Dunkelblau" +#~ msgid "Need account for login." +#~ msgstr "Benutzerkonto für Anmeldung wird benötigt." +#~ msgid "Need account for storing files." +#~ msgstr "Benutzerkonto für Speichern von Dateien wird benötigt." +#~ msgid "Negative stream size invalid" +#~ msgstr "Eine negative Stream-Größe ist ungültig" +#~ msgid "Net dropped connection or reset." +#~ msgstr "Netz hat die Verbindung verloren oder zurückgesetzt." +#~ msgid "Network is down." +#~ msgstr "Das Netzwerk ist ausgefallen." +#~ msgid "Network is unreachable." +#~ msgstr "Das Netzwerk ist nicht erreichbar." +#~ msgid "Network subsystem is unavailable." +#~ msgstr "Das Netzwerk-Subsystem ist nicht verfügbar." +#~ msgid "Network unreachable." +#~ msgstr "Das Netzwerk ist nicht erreichbar." +#~ msgid "New" +#~ msgstr "Neu" +#~ msgid "New &Directory" +#~ msgstr "Neues &Verzeichnis" +#~ msgid "New Folder" +#~ msgstr "Neuer Ordner" +#~ msgid "New components cannot be added to frame instances." +#~ msgstr "" +#~ "Zu Frame-Instanzen können keine neuen Komponenten hinzugefügt werden." +#~ msgid "Next|Go to the next tab" +#~ msgstr "&Fertig stellen" +#~ msgid "Nick" +#~ msgstr "Nick" +#~ msgid "" +#~ "No ActionBand style unit present in the uses clause.Your application must " +#~ "include either XPStyleActnCtrls, StdStyleActnCtrls or a third party " +#~ "ActionBand style unit in its uses clause." +#~ msgstr "" +#~ "In der uses-Klausel ist keine ActionBand-Attribut-Unit vorhanden.In Ihrer " +#~ "Anwendung muss XPStyleActnCtrls, StdStyleActnCtrls oder eine ActionBand-" +#~ "Attribut-Unit in der uses-Klausel vorhanden sein." +#~ msgid "No Class is regisgtered to implement interface %s" +#~ msgstr "Keine Klasse zum Implementieren der Schnittstelle %s registriert" +#~ msgid "No Content" +#~ msgstr "Kein Inhalt" +#~ msgid "No Dispatcher set" +#~ msgstr "Kein Dispatcher eingerichtet" +#~ msgid "No Help Manager installed." +#~ msgstr "Kein Hilfemanager installiert." +#~ msgid "No Install Options selected" +#~ msgstr "Es sind keine Installationsoptionen ausgewählt" +#~ msgid "No Message processing node set" +#~ msgstr "Kein Knoten zur Meldungsverarbeitung festgelegt" +#~ msgid "No Native to Message converter set" +#~ msgstr "Kein Konverter (Nativ zu Meldung) eingerichtet" +#~ msgid "No OnGetItem event handler assigned" +#~ msgstr "Es wurde keine OnGetItem-Ereignisbehandlung zugewiesen" +#~ msgid "No OnListDirectory event found!" +#~ msgstr "Es wurde kein Ereignis OnListDirectory gefunden!" +#~ msgid "No OnNewGroupsList event has been defined." +#~ msgstr "Es wurde kein Ereignis OnNewGroupsList definiert." +#~ msgid "No OnNewNewsList event has been defined." +#~ msgstr "Es wurde kein Ereignis OnNewNewsList definiert." +#~ msgid "No OnNewsgroupList event has been defined." +#~ msgstr "Es wurde kein Ereignis OnNewsgroupList definiert." +#~ msgid "No PSecPkgInfo specified" +#~ msgstr "Es wurde kein PSecPkgInfo angegeben" +#~ msgid "No Preview Available" +#~ msgstr "Keine Vorschau verfügbar" +#~ msgid "No Table of Contents found." +#~ msgstr "Kein Inhaltsverzeichnis gefunden" +#~ msgid "" +#~ "No URL property set - please specify the URL of the Service you wish to " +#~ "connect to" +#~ msgstr "" +#~ "URL-Eigenschaft nicht gesetzt - geben Sie die URL des Services an, zu dem " +#~ "Sie verbunden werden möchten" +#~ msgid "No URL was specified for 'GET'" +#~ msgstr "Für 'GET' wurde keine URL angegeben" +#~ msgid "No User: Port pair is not used or not used by an identifiable user" +#~ msgstr "" +#~ "Kein Benutzer: Port-Paar wird nicht oder nicht von identifizierbarem " +#~ "Benutzer verwendet" +#~ msgid "No WSDL document associated with WSDLView" +#~ msgstr "Kein WSDL-Dokument zugeordnet zu WSDLView" +#~ msgid "" +#~ "No WSDL or URL property was set in the THTTPRIO component. You must set " +#~ "the WSDL or URL property before invoking the Web Service" +#~ msgstr "" +#~ "In der THTTPPRIO-Komponente wurde keine WSDL- oder URL-Eigenschaft " +#~ "gesetzt. Vor Aufruf des Web Service muss eine dieser Eigenschaften " +#~ "gesetzt sein" +#~ msgid "No access to temporary file" +#~ msgstr "Kein Zugriff auf temporäre Datei" +#~ msgid "No access to temporary file: check TMPDIR setting" +#~ msgstr "Kein Zugriff auf temporäre Datei: prüfe TMPDIR-Einstellung" +#~ msgid "No active document" +#~ msgstr "Kein aktives Dokument" +#~ msgid "No authentication handler has been specified." +#~ msgstr "Es wurde keine Authentifizierungsbehandlung angegeben." +#~ msgid "No authority could be contacted for authentication." +#~ msgstr "" +#~ "Für die Authentifizierung konnte keine geeignete Stelle kontaktiert " +#~ "werden." +#~ msgid "No automatically activated data modules" +#~ msgstr "Keine automatisch aktivierten Datenmodule" +#~ msgid "No bindings specified." +#~ msgstr "Es wurde keine Bindung angegeben." +#~ msgid "No buffer space available." +#~ msgstr "Es ist kein Pufferplatz verfügbar." +#~ msgid "No class registered for invokable interface %s" +#~ msgstr "Keine Klasse registriert für aufrufbare Schnittstelle %s" +#~ msgid "No command handler found." +#~ msgstr "Es wurde kein Handler für Anweisungen gefunden." +#~ msgid "No context-sensitive Help installed." +#~ msgstr "Keine kontextsensitive Hilfe installiert." +#~ msgid "No context-sensitive help installed" +#~ msgstr "Keine kontextsensitive Hilfe installiert" +#~ msgid "No credential handle acquired" +#~ msgstr "Es wurde kein Beglaubigungs-Handle geholt" +#~ msgid "No credentials are available in the security package" +#~ msgstr "Im Sicherheits-Package sind keine Beglaubigungen verfügbar" +#~ msgid "No data allowed" +#~ msgstr "Keine Daten erlaubt" +#~ msgid "No data to read." +#~ msgstr "Keine Daten für den Lesezugriff." +#~ msgid "No default browser is specified" +#~ msgstr "Es ist kein Standard-Browser eingetragen" +#~ msgid "No execute handler found." +#~ msgstr "Es wurde keine Ausführungsbehandlung gefunden." +#~ msgid "No help found for \"%s\"" +#~ msgstr "Keine Hilfe gefunden für \"%s\"" +#~ msgid "No help found for %s" +#~ msgstr "Für %s sind keine Hilfeinformationen vorhanden." +#~ msgid "No help keyword specified." +#~ msgstr "Es wurden keine Schlüsselwörter für die Hilfe angegeben." +#~ msgid "No host" +#~ msgstr "Kein Host" +#~ msgid "No interface registered for URL '%s'" +#~ msgstr "Keine registrierte Schnittstelle für URL '%s'" +#~ msgid "No interface registered for soap action '%s'" +#~ msgstr "Keine registrierte Schnittstelle für die SOAP-Aktion '%s'" +#~ msgid "No interface is registered to handle URL %s" +#~ msgstr "Keine Schnittstelle registriert für die Behandlung der URL %s" +#~ msgid "" +#~ "No invokable class registered that implements interface %s of (soap " +#~ "action/path) %s" +#~ msgstr "" +#~ "Zum Implementieren von Interface %s für (SOAP-Aktion/Pfad) %s ist keine " +#~ "aufrufbare Klasse registriert." +#~ msgid "No matching DOM Vendor: \"%s\"" +#~ msgstr "Kein entsprechender DOM-Hersteller: \"%s\"" +#~ msgid "" +#~ "No matching Kylix type was found for type: URI = %s, Name = %s on Node %s" +#~ msgstr "" +#~ "Keinen passenden Kylix-Typ gefunden für: URI = %s, Name = %s von Node %s" +#~ msgid "No method named '%s' is supported by interface '%s'" +#~ msgstr "Methode mit Namen '%s' wird von Interface '%s' nicht unterstützt" +#~ msgid "No modification allowed (readonly data)" +#~ msgstr "Keine Änderung erlaubt (Daten können nur gelesen werden)" +#~ msgid "No printer adapter available for printing" +#~ msgstr "Für das Drucken ist kein Druckeradapter verfügbar" +#~ msgid "No property pages are available for this control" +#~ msgstr "Für dieses Element sind keine Eigenschaftsseiten verfügbar" +#~ msgid "" +#~ "No request handlers handled this request. The WebAppComponents " +#~ "PageDispatcher, AdapterDispatcher or DispatchActions property may not be " +#~ "set." +#~ msgstr "" +#~ "Diese Anforderung wurde von keiner entsprechenden Routine behandelt. Die " +#~ "WebAppComponents-Eigenschaft PageDispatcher, AdapterDispatcher oder " +#~ "DispatchActions sind u.U. nicht gesetzt." +#~ msgid "No route to host." +#~ msgstr "Keine Route zum Host." +#~ msgid "No service available for URL %s" +#~ msgstr "Kein Dienst für die URL %s verfügbar" +#~ msgid "No topic-based Help installed." +#~ msgstr "Keine themenbasierte Hilfe installiert." +#~ msgid "No topic-based help system installed" +#~ msgstr "Es ist keine themenbasierte Hilfe installiert." +#~ msgid "Node \"%s\" not found" +#~ msgstr "Knoten \"%s\" nicht gefunden" +#~ msgid "Node cannot be null" +#~ msgstr "Knoten kann nicht null sein" +#~ msgid "Node is owned by a different document" +#~ msgstr "Der Knoten ist im Besitz eines anderen Dokuments" +#~ msgid "Node is readonly" +#~ msgstr "Knoten ist schreibgeschützt" +#~ msgid "Node not found" +#~ msgstr "Knoten nicht gefunden" +#~ msgid "Non Authenticated" +#~ msgstr "Nicht authentifiziert" +#~ msgid "Non-authoritative Information" +#~ msgstr "Nicht-autoritative Information" +#~ msgid "Non-authoritative response (try again or check DNS setup)." +#~ msgstr "" +#~ "Nicht-autoritative Antwort (Versuchen Sie es noch einmal oder überprüfen " +#~ "Sie das DNS-Setup)." +#~ msgid "Non-echo type response received" +#~ msgstr "Nicht-Echo-Antwort empfangen" +#~ msgid "Non-recoverable errors: FORMERR, REFUSED, NOTIMP." +#~ msgstr "Nicht behebbare Fehler: FORMERR, REFUSED, NOTIMP." +#~ msgid "None" +#~ msgstr "Ohne" +#~ msgid "Not Acceptable" +#~ msgstr "Nicht akzeptabel" +#~ msgid "Not Connected" +#~ msgstr "Nicht verbunden" +#~ msgid "Not Found" +#~ msgstr "Nicht gefunden" +#~ msgid "Not Implemented" +#~ msgstr "Nicht implementiert" +#~ msgid "Not Modified" +#~ msgstr "Nicht geändert" +#~ msgid "Not all bytes sent." +#~ msgstr "Es wurden nicht alle Bytes gesendet." +#~ msgid "Not connected to server." +#~ msgstr "Nicht mit Server verbunden." +#~ msgid "Not enough bytes received" +#~ msgstr "Es wurden nicht genügend Bytes empfangen" +#~ msgid "Not enough data in buffer." +#~ msgstr "Nicht genügend Daten im Puffer." +#~ msgid "Not enough memory is available to complete this request" +#~ msgstr "Für diese Anforderung steht nicht genügend Speicher zur Verfügung" +#~ msgid "Not found" +#~ msgstr "Nicht gefunden" +#~ msgid "Not in edit mode" +#~ msgstr "Nicht im Bearbeitungs-Modus" +#~ msgid "Not logged in." +#~ msgstr "Nicht angemeldet." +#~ msgid "Not supported" +#~ msgstr "Nicht unterstützt" +#~ msgid "Notice: normal but significant condition" +#~ msgstr "Ankündigung: Normaler, aber bedeutender Zustand" +#~ msgid "Object does not support scripting. Class: %0:s" +#~ msgstr "Objekt unterstützt das Scripting nicht. Klasse: %0:s" +#~ msgid "Object type name required as parameter value" +#~ msgstr "Name des Objekttyps als Parameterwert erforderlich" +#~ msgid "Object type not supported." +#~ msgstr "Objekttyp nicht unterstützt." +#~ msgid "ObjectView must be True for Table with Object fields" +#~ msgstr "ObjectView muss bei Tabellen mit Objektfeldern True sein" +#~ msgid "Odd byte position not valid for WideString" +#~ msgstr "Eine ungerade Byte-Position ist für WideString nicht zulässig" +#~ msgid "Odd size not valid for WideString" +#~ msgstr "Eine ungerade Größe ist für WideString nicht zulässig" +#~ msgid "Ok" +#~ msgstr "Ok" +#~ msgid "Olive" +#~ msgstr "Olivgrün" +#~ msgid "OnDataAvailable event is nil." +#~ msgstr "Ereignis OnDataAvailable ist nil." +#~ msgid "OnExecute not assigned." +#~ msgstr "OnExecute nicht zugewiesen." +#~ msgid "Only one FaultCode element allowed" +#~ msgstr "Nur ein FaultCode-Element zulässig" +#~ msgid "Only one FaultString element allowed" +#~ msgstr "Nur ein FaultString-Element zulässig" +#~ msgid "Only one TIdAntiFreeze can exist per application." +#~ msgstr "Pro Anwendung kann es nur ein TIdAntiFreeze geben." +#~ msgid "Open MyBase table" +#~ msgstr "MyBase-Tabelle öffnen" +#~ msgid "Open Picture" +#~ msgstr "Dialog" +#~ msgid "Open Transformation File" +#~ msgstr "Transformationsdatei öffnen" +#~ msgid "Open Xml File" +#~ msgstr "Xml-Datei öffnen" +#~ msgid "Open as &read-only" +#~ msgstr "Nur zum &Lesen öffnen" +#~ msgid "Open trace log file" +#~ msgstr "Protokolldatei für Ablaufverfolgung öffnen" +#~ msgid "Open with..." +#~ msgstr "Öffnen mit..." +#~ msgid "Open|Opens an existing file" +#~ msgstr "Öffnen|Vorhandene Datei öffnen" +#~ msgid "Operation already in progress." +#~ msgstr "Die Operation wird bereits durchgeführt." +#~ msgid "Operation not allowed on a unidirectional dataset" +#~ msgstr "" +#~ "Diese Operation ist bei einer unidirektionalen Datenemenge nicht gestattet" +#~ msgid "Operation not allowed on sorted list" +#~ msgstr "Operation für sortierte Listen nicht zulässig" +#~ msgid "Operation not allowed with aggregates active" +#~ msgstr "Operation mit aktiven Aggregaten nicht zulässig" +#~ msgid "Operation not supported" +#~ msgstr "Operation nicht unterstützt" +#~ msgid "Operation not supported on socket." +#~ msgstr "Die Operation wird bei Socket nicht unterstützt." +#~ msgid "" +#~ "Operation not supported. %s component does not support " +#~ "IGetWebComponentList" +#~ msgstr "" +#~ "Operation wird nicht unterstützt. Komponente %s unterstützt nicht " +#~ "IGetWebComponentList" +#~ msgid "Operation now in progress." +#~ msgstr "Die Operation wird gerade durchgeführt." +#~ msgid "Operation would block. " +#~ msgstr "Die Operation würde blockieren. " +#~ msgid "Option not set to allow Native type to be set to NULL" +#~ msgstr "Option zum Setzen des Typs Native auf NULL nicht gesetzt" +#~ msgid "Original Value" +#~ msgstr "Originalwert" +#~ msgid "OtherNick" +#~ msgstr "OtherNick" +#~ msgid "Ounces" +#~ msgstr "Unze" +#~ msgid "Overflow while converting variant of type (%s) into type (%s)" +#~ msgstr "" +#~ "Überlauf bei der Konvertierung einer Variante vom Typ (%s) in Typ (%s)" +#~ msgid "Owner" +#~ msgstr "Besitzer" +#~ msgid "Owner is not a TCustomHeaderSection" +#~ msgstr "Besitzer ist kein TCustomHeaderSection" +#~ msgid "PNGs" +#~ msgstr "PNGs" +#~ msgid "POP3 proxy ready" +#~ msgstr "POP3-Proxy bereit" +#~ msgid "POP3 proxy signing off" +#~ msgstr "POP3-Proxy wird beendet" +#~ msgid "Paces" +#~ msgstr "Schritt" +#~ msgid "Package Size Too Big." +#~ msgstr "Package-Größe zu hoch" +#~ msgid "Packages are not supported by '%s' Server" +#~ msgstr "Packages werden vom '%s'-Server nicht unterstützt" +#~ msgid "Page %s does not support inclusion" +#~ msgstr "Seite %s unterstützt keine Inklusion" +#~ msgid "Page Set&up..." +#~ msgstr "Seite e&inrichten..." +#~ msgid "Page access denied" +#~ msgstr "Zugriff auf Seite verweigert" +#~ msgid "Pages" +#~ msgstr "Seiten" +#~ msgid "Parameter %d required for method %s" +#~ msgstr "Parameter %d erforderlich für Methode %s" +#~ msgid "Parameter %s on Method %s of Interface %s has no RTTI" +#~ msgstr "Parameter %s der Methode %s der Schnittstelle %s hat kein RTTI" +#~ msgid "Parameter expected" +#~ msgstr "Parameter erwartet" +#~ msgid "Parent given is not a parent of '%s'" +#~ msgstr "" +#~ "Das angegebene übergeordnete Element ist kein übergeordnetes Element von " +#~ "'%s'" +#~ msgid "ParentConnection is not assigned" +#~ msgstr "ParentConnection ist nicht zugewiesen" +#~ msgid "Parsecs" +#~ msgstr "Parsecs" +#~ msgid "Partial Content" +#~ msgstr "Teilinhalt" +#~ msgid "Pass&word:" +#~ msgstr "Pass&wort:" +#~ msgid "Password" +#~ msgstr "Passwort" +#~ msgid "Password must not be blank" +#~ msgstr "Passwort muss angegeben werden" +#~ msgid "Password: " +#~ msgstr "Passwort: " +#~ msgid "Paste" +#~ msgstr "Einfügen" +#~ msgid "Paste|Inserts Clipboard contents" +#~ msgstr "Einfügen|Inhalt der Zwischenablage einfügen" +#~ msgid "Path" +#~ msgstr "Pfad" +#~ msgid "Personalized Menus and Toolbars" +#~ msgstr "Individuelle Menüs und Symbolleisten" +#~ msgid "Picas" +#~ msgstr "Pica" +#~ msgid "Pixmaps" +#~ msgstr "Pixmaps" +#~ msgid "Points" +#~ msgstr "Punkt" +#~ msgid "Polite people say HELO" +#~ msgstr "Höfliche Menschen sagen HALLO" +#~ msgid "Port Type" +#~ msgstr "Port-Typ" +#~ msgid "Port:" +#~ msgstr "Port:" +#~ msgid "PortName" +#~ msgstr "Port-Name" +#~ msgid "Pounds" +#~ msgstr "Pfund" +#~ msgid "Precondition Failed" +#~ msgstr "Vorbedingung fehlgeschlagen" +#~ msgid "PreviewLabel" +#~ msgstr "Labelvorschau" +#~ msgid "Previous|Go back to the previous tab" +#~ msgstr "Tab" +#~ msgid "Print Set&up..." +#~ msgstr "&Druckereinstellungen..." +#~ msgid "Print Setup" +#~ msgstr "Druckereinstellungen" +#~ msgid "Project Co-Coordinator" +#~ msgstr "Projekt-Co-Koordinator" +#~ msgid "Project Coordinator" +#~ msgstr "Projekt-Koordinator" +#~ msgid "Property %s does not exist" +#~ msgstr "Eigenschaft %s existiert nicht." +#~ msgid "Property '%s' has not been initialized on component '%s'" +#~ msgstr "Eigenschaft '%s' wurde für Komponente '%s' nicht initialisiert" +#~ msgid "Property or Method \"%s\" is not supported by DOM Vendor \"%s\"" +#~ msgstr "" +#~ "Eigenschaft oder Methode \"%s\" wird von diesem DOM-Hersteller \"%s\" " +#~ "nicht unterstützt" +#~ msgid "Protocol family not supported." +#~ msgstr "Die Protokollfamilie wird nicht unterstützt." +#~ msgid "Protocol field is empty" +#~ msgstr "Protokollfeld ist leer" +#~ msgid "Protocol not supported." +#~ msgstr "Das Protokoll wird nicht unterstützt." +#~ msgid "Protocol wrong type for socket." +#~ msgstr "Das Protokoll hat für Socket den falschen Typ." +#~ msgid "Proxy Authentication Required" +#~ msgstr "Proxy-Authentifizierung erforderlich" +#~ msgid "Purple" +#~ msgstr "Purpur" +#~ msgid "Queue %s status: %s" +#~ msgstr "Warteschlange %s Status: %s" +#~ msgid "Quit key hit" +#~ msgstr "Taste zum Verlassen gedrückt" +#~ msgid "RCode NO Error" +#~ msgstr "RCode NO Fehler" +#~ msgid "RESPONSE" +#~ msgstr "RESPONSE" +#~ msgid "Radio items must have a Controller as a parent" +#~ msgstr "" +#~ "Optionsfelder müssen einen Controller als übergeordnetes Element besitzen" +#~ msgid "Range check error for variant of type (%s)" +#~ msgstr "Fehler bei Bereichsprüfung für Variant des Typs (%s)" +#~ msgid "" +#~ "Range check error while converting variant of type (%s) into type (%s)" +#~ msgstr "" +#~ "Fehler bei Bereichsprüfung bei der Konvertierung von Variant von Typ (%s) " +#~ "zu Typ (%s)" +#~ msgid "Range of %d to %d is invalid" +#~ msgstr "Der Bereich von %d bis %d ist ungültig" +#~ msgid "Rankine" +#~ msgstr "Rangordnung" +#~ msgid "Raw Receive Error = 0." +#~ msgstr "Raw Receive-Fehler = 0." +#~ msgid "Re&move all" +#~ msgstr "&Alle entfernen" +#~ msgid "Read Timeout" +#~ msgstr "Zeitüberschreitung beim Lesen" +#~ msgid "Real name" +#~ msgstr "Wirklicher Name" +#~ msgid "Reason: %s\n" +#~ msgstr "Grund: %s\n" +#~ msgid "Reaumur" +#~ msgstr "Reaumur" +#~ msgid "Receive" +#~ msgstr "Erhalten" +#~ msgid "Receive control file" +#~ msgstr "Empfang von Steuerungsdatei" +#~ msgid "Receive data file" +#~ msgstr "Empfang von Datendatei" +#~ msgid "Received Packet is too small. %d" +#~ msgstr "Empfangenes Paket ist zu klein. %d" +#~ msgid "Received Packet is too small. Less than 12 bytes %d" +#~ msgstr "Empfangenes Paket ist zu klein. Weniger als 12 Byte %d" +#~ msgid "Received Packet is too small. Less than 4 bytes %d" +#~ msgstr "Empfangenes Paket ist zu klein. Weniger als 4 Byte %d" +#~ msgid "" +#~ "Received content of invalid Content-Type setting: %s - SOAP expects " +#~ "\"text/xml\"" +#~ msgstr "" +#~ "Empfang von Inhalt mit ungültigen Einstellungen für Inhaltstyp: %s - SOAP " +#~ "erwartet \"text/xml\"" +#~ msgid "Received someone else's packet" +#~ msgstr "Es ist ein Paket für einen anderen Empfänger angekommen" +#~ msgid "Reconnect at %s: %s" +#~ msgstr "Wieder verbinden bei %s: %s" +#~ msgid "Record not found or changed by another user" +#~ msgstr "Datensatz nicht gefunden oder von einem anderen Benutzer geändert" +#~ msgid "Recordset is not open" +#~ msgstr "Recordset ist nicht geöffnet" +#~ msgid "Recursion while doing a VarDataCastTo" +#~ msgstr "Rekursion beim Durchführen eines VarDataCastTo" +#~ msgid "Recursion while doing a VarDataClear" +#~ msgstr "Rekursion beim Durchführen eines VarDataClear" +#~ msgid "Recursion while doing a VarDataCopy" +#~ msgstr "Rekursion beim Durchführen eines VarDataCopy" +#~ msgid "Recursion while doing a VarDataCopyNoInd" +#~ msgstr "Rekursion beim Durchführen eines VarDataCopyNoInd" +#~ msgid "Recursion while doing a VarDataInit" +#~ msgstr "Rekursion beim Durchführen eines VarDataInit" +#~ msgid "Recv " +#~ msgstr "Empf " +#~ msgid "Red" +#~ msgstr "Rot" +#~ msgid "Redo" +#~ msgstr "Widerrufen" +#~ msgid "Refresh" +#~ msgstr "Aktualisieren" +#~ msgid "Refresh is only supported if the FileName or XML properties are set" +#~ msgstr "" +#~ "Aktualisierung wird nur unterstützt, wenn die Eigenschaften FileName oder " +#~ "XML gesetzt sind" +#~ msgid "Registered Types" +#~ msgstr "Registrierte Typen" +#~ msgid "Reload" +#~ msgstr "Neu laden" +#~ msgid "Remotable Type %s not registered" +#~ msgstr "Typ %s ist nicht registriert" +#~ msgid "" +#~ "Remote Method Call: unsupported calling convention %s for method %s on " +#~ "interface %s" +#~ msgstr "" +#~ "Remote-Methodenaufruf: nicht unterstützte Aufrufkonvention %s für Methode " +#~ "%s in Schnittstelle %s" +#~ msgid "Remove" +#~ msgstr "Entfernen" +#~ msgid "Rep&lace with:" +#~ msgstr "&Ersetzen durch:" +#~ msgid "Replace" +#~ msgstr "Ersetzen" +#~ msgid "Replace &All" +#~ msgstr "&Alles ersetzen" +#~ msgid "Replace|Replaces specific text with different text" +#~ msgstr "Ersetzen|Angegebenen Text durch neuen Text ersetzen" +#~ msgid "Reply %s on Job ID %s" +#~ msgstr "Antwort %s auf Job-ID %s" +#~ msgid "" +#~ "Reply Timed Out: The server did not return a response and the query has " +#~ "been abandoned" +#~ msgstr "" +#~ "Zeit überschritten bei Antwort: Der Server gab keine Antwort und die " +#~ "Abfrage wurde nicht eingestellt" +#~ msgid "Request Entity To Long" +#~ msgstr "Anforderungs-Entität zu lang" +#~ msgid "Request Timeout" +#~ msgstr "Zeitüberschreitung für Anforderung" +#~ msgid "Request rejected because SOCKS server cannot connect." +#~ msgstr "" +#~ "Die Anforderung wurde zurückgewiesen, da der SOCKS-Server keine " +#~ "Verbindung herstellen konnte." +#~ msgid "" +#~ "Request rejected because the client program and identd report different " +#~ "user-ids." +#~ msgstr "" +#~ "Die Anforderung wurde zurückgewiesen, da das Client-Programm und identd " +#~ "verschiedene Anwender-IDs melden." +#~ msgid "Request rejected or failed." +#~ msgstr "Anforderung zurückgewiesen oder fehlgeschlagen." +#~ msgid "Request-URI Too Long. 256 Chars max" +#~ msgstr "Anforderungs-URI zu lang. Max. 256 Zeichen" +#~ msgid "RequestCount:" +#~ msgstr "Anforderungen:" +#~ msgid "Requested action aborted: local error in processing." +#~ msgstr "Angeforderte Aktion abgebrochen: Lokaler Fehler bei Bearbeitung." +#~ msgid "Requested action aborted: page type unknown." +#~ msgstr "Angeforderte Aktion abgebrochen: Seitenzahl unbekannt." +#~ msgid "Requested action not taken." +#~ msgstr "Angeforderte Aktion nicht durchgeführt." +#~ msgid "Requested file action aborted." +#~ msgstr "Angeforderte Dateiaktion nicht abgebrochen." +#~ msgid "Requested file action not taken." +#~ msgstr "Angeforderte Dateiaktion nicht durchgeführt." +#~ msgid "Requested file action okay, completed." +#~ msgstr "Angeforderte Dateiaktion OK, abgeschlossen." +#~ msgid "Requested file action pending further information." +#~ msgstr "Angeforderte Dateiaktion steht aus wegen Informationsbedarf." +#~ msgid "Requires Connection before opening" +#~ msgstr "Vor dem Öffnen ist eine Verbindung erforderlich" +#~ msgid "Reset Content" +#~ msgstr "Inhalt zurücksetzen" +#~ msgid "Reset Toolbar" +#~ msgstr "Symbolleiste zurücksetzen" +#~ msgid "Reset Usage Data" +#~ msgstr "Optionen" +#~ msgid "Reset all usage data?" +#~ msgstr "Alle verwendeten Daten zurücksetzen" +#~ msgid "Resolving hostname %s." +#~ msgstr "Host-Name %s wird aufgelöst." +#~ msgid "Restore Database Files" +#~ msgstr "Datenbankdateien wiederherstellen" +#~ msgid "Retired/Past Contributors" +#~ msgstr "Pensionierte/ehemalige Mitarbeiter" +#~ msgid "Return" +#~ msgstr "Eingabe" +#~ msgid "Rods" +#~ msgstr "Messrute" +#~ msgid "Row not found in %s" +#~ msgstr "Reihe in %s nicht gefunden" +#~ msgid "Run" +#~ msgstr "Start" +#~ msgid "Run|Runs an application" +#~ msgstr "Start" +#~ msgid "S&top Server" +#~ msgstr "Server s&toppen" +#~ msgid "S&ub Items" +#~ msgstr "&Untereinträge" +#~ msgid "SOAP Response Packet: result element expected, received \"%s\"" +#~ msgstr "SOAP-Antwortpaket: Ergebniselement erwartet, \"%s\" gefunden" +#~ msgid "SQL Error: Error mapping failed" +#~ msgstr "SQL-Fehler: Fehlerzuweisung gescheitert" +#~ msgid "SQLConnection property required for this operation" +#~ msgstr "Für diese Operation ist die Eigenschaft SQLConnection erforderlich" +#~ msgid "SSL certificate request error." +#~ msgstr "Fehler bei der Anforderung eines SSL-Zertifikats." +#~ msgid "SSL connection has dropped." +#~ msgstr "Die SSL-Verbindung ging verloren." +#~ msgid "SSL library internal error." +#~ msgstr "SSL-Bibliotheksinterner Fehler." +#~ msgid "SSL status: \"%s\"" +#~ msgstr "SSL-Status: \"%s\"" +#~ msgid "SSPI %s returns error #%d(0x%x): %s" +#~ msgstr "SSPI %s gibt Fehler #%d(0x%x) zurück: %s" +#~ msgid "SSPI interface has failed to initialise properly" +#~ msgstr "SSPI-Interface hat sich nicht richtig initialisiert" +#~ msgid "Save" +#~ msgstr "Speichern" +#~ msgid "Save %s as" +#~ msgstr "%s speichern unter" +#~ msgid "Save &As..." +#~ msgstr "Speichern &unter..." +#~ msgid "Save As" +#~ msgstr "Speichern unter" +#~ msgid "Save As|Saves the active file with a new name" +#~ msgstr "Speichern unter|Aktive Datei unter einem neuen Namen speichern" +#~ msgid "Save Picture" +#~ msgstr "Dialog" +#~ msgid "Save Picture As" +#~ msgstr "Bild speichern unter" +#~ msgid "Script Error" +#~ msgstr "Script-Fehler" +#~ msgid "Script Object expected" +#~ msgstr "Script-Objekt erwartet" +#~ msgid "Script engine not found: %s." +#~ msgstr "Script-Engine nicht gefunden: %s." +#~ msgid "Script execution timed out after %d seconds" +#~ msgstr "Zeit der Script-Ausführung nach %d Sekunden überschritten" +#~ msgid "Scroll Bar" +#~ msgstr "Bildlaufleiste" +#~ msgid "Se&ttings:" +#~ msgstr "Eins&tellungen:" +#~ msgid "Search" +#~ msgstr "Suchen" +#~ msgid "Seconds" +#~ msgstr "Sekunde" +#~ msgid "See Other" +#~ msgstr "Siehe Weitere" +#~ msgid "Sele&cted Index:" +#~ msgstr "Ausgewählt-&Index:" +#~ msgid "Select &All" +#~ msgstr "Alles &markieren" +#~ msgid "Select &Color..." +#~ msgstr "&Farbe wählen..." +#~ msgid "Select &Font..." +#~ msgstr "&Schriftart wählen..." +#~ msgid "Select All" +#~ msgstr "Alles markieren" +#~ msgid "Select All|Selects the entire document" +#~ msgstr "Alles markieren|Markiert das gesamte Dokument" +#~ msgid "Selected" +#~ msgstr "Ausgewählte" +#~ msgid "Selected DOM Vendor does not support this property or method" +#~ msgstr "" +#~ "Der gewählte DOM-Hersteller unterstützt diese Eigenschaft oder Methode " +#~ "nicht" +#~ msgid "" +#~ "Selection contains a component introduced in an ancestor form which " +#~ "cannot be deleted" +#~ msgstr "" +#~ "Auswahl enthält eine Komponente, die in einem Vorfahr-Formular eingeführt " +#~ "wurde, das nicht gelöscht werden kann." +#~ msgid "Send" +#~ msgstr "Senden" +#~ msgid "Send a message" +#~ msgstr "Eine Botschaft senden" +#~ msgid "Send email" +#~ msgstr "E-mail senden" +#~ msgid "Send to Back" +#~ msgstr "Nach hinten setzen" +#~ msgid "Sent " +#~ msgstr "Gesendet " +#~ msgid "Separator" +#~ msgstr "Separator" +#~ msgid "Server Connection not locatable when sending message" +#~ msgstr "" +#~ "Die Serververbindung ist beim Senden einer Botschaft nicht ausfindig zu " +#~ "machen" +#~ msgid "Server Returned Unknown Error" +#~ msgstr "Der Server gab einen unbekannten Fehler zurück" +#~ msgid "Server did not respond." +#~ msgstr "Server hat nicht geantwortet." +#~ msgid "Server do not support APOP (no timestamp)" +#~ msgstr "Server unterstützt kein APOP (kein Zeitstempel)" +#~ msgid "Server status: active" +#~ msgstr "Server-Status: aktiv" +#~ msgid "ServerInfo" +#~ msgstr "ServerInfo" +#~ msgid "Service Editor" +#~ msgstr "Service-Editor" +#~ msgid "Service Info Page" +#~ msgstr "Service Info-Seite" +#~ msgid "Service Unavailable" +#~ msgstr "Service nicht verfügbar" +#~ msgid "Service closing control connection." +#~ msgstr "Service schließt die Steuerverbindung." +#~ msgid "Service not available, closing control connection." +#~ msgstr "Service nicht verfügbar, Steuerverbindung wird geschlossen." +#~ msgid "Service ready for new user." +#~ msgstr "Service bereit für neuen Benutzer." +#~ msgid "Set Size Exceeded." +#~ msgstr "Mengengröße überschritten." +#~ msgid "Set the GroupRef property for the cmGroupRef content model" +#~ msgstr "" +#~ "Legen Sie die Eigenschaft GroupRef für das cmGroupRef-Inhaltsmodell fest" +#~ msgid "SetCipher failed." +#~ msgstr "SetCipher fehlgeschlagen." +#~ msgid "Show &Hidden Files" +#~ msgstr "Verborgene Dateien an&zeigen" +#~ msgid "Show &tips on toolbars" +#~ msgstr "&Kurzhinweise in Symbolleisten anzeigen" +#~ msgid "Show f&ull menus after a short delay" +#~ msgstr "&Nach kurzer Verzögerung vollständige Menüs anzeigen" +#~ msgid "Show shortcut keys in tips" +#~ msgstr "&Tastenkürzel in Kurzhinweisen anzeigen" +#~ msgid "Signing Off" +#~ msgstr "Beendigung" +#~ msgid "Silver" +#~ msgstr "Silber" +#~ msgid "Size" +#~ msgstr "Größe" +#~ msgid "Size Mismatch - Field %s size is too small for data" +#~ msgstr "Größenfehler - Feld %s ist zu klein für die Daten" +#~ msgid "Size(Bytes)" +#~ msgstr "Größe(Bytes)" +#~ msgid "Skip" +#~ msgstr "Überspringen" +#~ msgid "Sky Blue" +#~ msgstr "Himmelblau" +#~ msgid "Small Icon view" +#~ msgstr "Kleine Symoble anzeigen" +#~ msgid "" +#~ "Soap header %s with attribute 'mustUnderstand' set to true was not handled" +#~ msgstr "" +#~ "SOAP-Header %s mit Attribut 'mustUnderstand' true wurde nicht behandelt" +#~ msgid "" +#~ "Socket Error # %d\n" +#~ "%s" +#~ msgstr "" +#~ "Socket-Fehler # %d\n" +#~ "%s" +#~ msgid "Socket is already connected." +#~ msgstr "Socket ist bereits verbunden." +#~ msgid "Socket is not connected." +#~ msgstr "Socket ist nicht verbunden." +#~ msgid "Socket operation on non-socket." +#~ msgstr "Socket-Operation auf Nicht-Socket." +#~ msgid "Socket read error" +#~ msgstr "Fehler beim Lesen von Socket" +#~ msgid "Socket type not supported." +#~ msgstr "Sockettyp wird nicht unterstützt." +#~ msgid "Socks server did not respond." +#~ msgstr "Socks-Server hat nicht geantwortet." +#~ msgid "Software caused connection abort." +#~ msgstr "Die Software hat den Abbruch der Verbindung verursacht." +#~ msgid "SourceDirectory is not set" +#~ msgstr "SourceDirectory nicht gesetzt" +#~ msgid "SquareCentimeters" +#~ msgstr "Quadratzentimeter" +#~ msgid "SquareDecameters" +#~ msgstr "Quadratdekameter" +#~ msgid "SquareDecimeters" +#~ msgstr "Quadratdezimeter" +#~ msgid "SquareFeet" +#~ msgstr "Quadratfuß" +#~ msgid "SquareHectometers" +#~ msgstr "Quadrathektometer" +#~ msgid "SquareInches" +#~ msgstr "Quadratzoll" +#~ msgid "SquareKilometers" +#~ msgstr "Quadratkilometer" +#~ msgid "SquareMeters" +#~ msgstr "Quadratmeter" +#~ msgid "SquareMiles" +#~ msgstr "Quadratmeilen" +#~ msgid "SquareMillimeters" +#~ msgstr "Quadratmillimeter" +#~ msgid "SquareRods" +#~ msgstr "Quadratrute" +#~ msgid "SquareYards" +#~ msgstr "Quadrat-Yard" +#~ msgid "St&atistics" +#~ msgstr "St&atistik" +#~ msgid "Stale NFS file handle." +#~ msgstr "Abgelaufenes NFS-Datei-Handle." +#~ msgid "Standard" +#~ msgstr "Standard" +#~ msgid "Standard Style" +#~ msgstr "Standard-Attribut" +#~ msgid "Start" +#~ msgstr "Start" +#~ msgid "Start mail input; end with ." +#~ msgstr "Mail-Eingabe starten; beenden mit ." +#~ msgid "Starting FTP transfer" +#~ msgstr "FTP-Transfer wird gestartet" +#~ msgid "Stat " +#~ msgstr "Stat " +#~ msgid "Steres" +#~ msgstr "Ster" +#~ msgid "Stones" +#~ msgstr "Stones" +#~ msgid "Stop" +#~ msgstr "Stop" +#~ msgid "Stopped" +#~ msgstr "Angehalten" +#~ msgid "Stored Procedures not supported by '%s' Server" +#~ msgstr "Stored Procedures werden vom '%s'-Server nicht unterstützt" +#~ msgid "Strikeout" +#~ msgstr "Durchstreichen" +#~ msgid "String" +#~ msgstr "String" +#~ msgid "String list editor" +#~ msgstr "String-Listen-Editor" +#~ msgid "String parameter expected" +#~ msgstr "String-Parameter erwartet" +#~ msgid "Stringlist not initialized!" +#~ msgstr "Die String-Liste ist nicht initialisiert!" +#~ msgid "Structure set to %s." +#~ msgstr "Struktur gesetzt auf %s." +#~ msgid "Sub Item &Properties" +#~ msgstr "Eigenschaften des Untereintrags" +#~ msgid "Successful Connection" +#~ msgstr "Erfogreiche Verbindung" +#~ msgid "Successful execution" +#~ msgstr "Ausführung erfolgreich" +#~ msgid "Successfull API call" +#~ msgstr "Erfolgreicher API-Aufruf" +#~ msgid "Switching protocols" +#~ msgstr "Protokollumschaltung" +#~ msgid "Syntax Error - Command not understood: %s" +#~ msgstr "Syntaxfehler - Anweisung unverständlich: %s" +#~ msgid "Syntax error, command unrecognized." +#~ msgstr "Syntaxfehler, Anweisung nicht erkannt" +#~ msgid "" +#~ "System Error. Code: %d.\n" +#~ "%s" +#~ msgstr "" +#~ "Systemfehler. Code: %d.\n" +#~ "%s" +#~ msgid "TAggregateStream Error: no internal streams" +#~ msgstr "TAggregateStream-Fehler: Keine interne Streams" +#~ msgid "TIdIRC 1.061 by Steve Williams" +#~ msgstr "TIdIRC 1.061 von Steve Williams" +#~ msgid "TIdMessagePart can not be created. Use descendant classes. " +#~ msgstr "" +#~ "TIdMessagePart kann nicht erzeugt werden. Verwenden Sie abgeleitete " +#~ "Klassen. " +#~ msgid "TIdSNPP Mess command only supports single line Messages." +#~ msgstr "TIdSNPP-Anweisung Mess unterstützt nur einzeilige Botschaften." +#~ msgid "TMenu.SetForm: argument must be TCustomForm" +#~ msgstr "Das Argument von TMenu.SetForm: muss ein TCustomForm sein" +#~ msgid "TPB Constant (%s) is unknown" +#~ msgstr "TPB-Konstante (%s) ist unbekannt." +#~ msgid "TStrings descendant %s failed to call inherited constructor" +#~ msgstr "" +#~ "Der Nachkomme von TStrings %s konnte den geerbten Konstruktor nicht " +#~ "aufrufen" +#~ msgid "TTL expired." +#~ msgstr "TTL abgelaufen." +#~ msgid "Table/Procedure not found" +#~ msgstr "Tabelle/Prozedur wurde nicht gefunden" +#~ msgid "Te&xt:" +#~ msgstr "Te&xt:" +#~ msgid "Teal" +#~ msgstr "Grünblau" +#~ msgid "Temperature" +#~ msgstr "Temperatur" +#~ msgid "Terminate Thread Timeout" +#~ msgstr "Zeitüberschreitung bei Beenden von Thread" +#~ msgid "Text file (*.txt)|*.txt|Any file (*)|*" +#~ msgstr "Textdatei (*.txt)|*.txt|Alle Dateien (*)|*" +#~ msgid "Text file (*.txt)|*.txt|Any file (*.*)|*.*" +#~ msgstr "Textdatei (*.txt)|*.txt|Alle Dateien (*.*)|*.*" +#~ msgid "Text files (*.txt)|*.txt|All files (*.*)|*.*" +#~ msgstr "Textdateien (*.txt)|*.txt|Alle Dateien (*.*)|*.*" +#~ msgid "" +#~ "Text files (*.txt)|*.txt|Shell scripts (*.sh)|*.sh|Config files (*.conf)|" +#~ "*.conf|All files (*)|*\n" +#~ msgstr "" +#~ "Textdateien (*.txt)|*.txt|Shellskripte (*.sh)|*.sh|Konfigurationsdateien " +#~ "(*.conf)|*.conf|Alle Dateien (*)|*\n" +#~ msgid "" +#~ "Text files (*.txt)|Config files (*.conf)|Shell scripts (*.sh)|All files " +#~ "(*)\n" +#~ msgstr "" +#~ "Textdateien (*.txt)|Konfigurationsdateien (*.conf)|Shellskripte (*.sh)|" +#~ "Alle Dateien (*)\n" +#~ msgid "Text not found: \"%s\"" +#~ msgstr "Text nicht gefunden: \"%s\"" +#~ msgid "The Local Security Authority cannot be contacted" +#~ msgstr "Die lokale Sicherheitsautorität kann nicht kontaktiert werden" +#~ msgid "The buffers supplied to a function was too small." +#~ msgstr "Die der Funktion mitgegebenen Puffer sind zu klein." +#~ msgid "The caller is not the owner of the desired credentials" +#~ msgstr "Der Aufrufer ist nicht der Besitzer der gewünschten Beglaubigung" +#~ msgid "The certificate chain was issued by an untrusted authority." +#~ msgstr "" +#~ "Die Zertifikatskette wurde von einer nicht vertrauenswürdigen Autorität " +#~ "ausgegeben." +#~ msgid "" +#~ "The client and server cannot communicate, because they do not possess a " +#~ "common algorithm." +#~ msgstr "" +#~ "Client und Server können nicht kommunizieren, da sie keinen gemeinsamen " +#~ "Algorithmus besitzen." +#~ msgid "The clocks on the client and server machines are skewed." +#~ msgstr "Die Uhrzeit auf Client und Server ist unterschiedlich." +#~ msgid "The context data must be renegotiated with the peer." +#~ msgstr "Die Kontextdaten müssen mit dem Peer neu ausgehandelt werden." +#~ msgid "The context has expired and can no longer be used." +#~ msgstr "Der Kontext ist abgelaufen und kann nicht mehr verwendet werden." +#~ msgid "The credentials supplied to the package were not recognized" +#~ msgstr "Die Beglaubigungen aus dem Package wurden nicht erkannt" +#~ msgid "" +#~ "The credentials supplied were not complete, and could not be verified. " +#~ "Additional information can be returned from the context." +#~ msgstr "" +#~ "Die aufgeführten Beglaubigungen waren unvollständig und konnten nicht " +#~ "verifiziert werden. Zusatzinformationen können aus dem Kontext " +#~ "zurückgegeben werden." +#~ msgid "" +#~ "The credentials supplied were not complete, and could not be verified. " +#~ "The context could not be initialized." +#~ msgstr "" +#~ "Die aufgeführten Beglaubigungen waren unvollständig und konnten nicht " +#~ "verifiziert werden. Der Kontext konnte nicht initialisiert werden." +#~ msgid "The following SITE commands are supported: HELP DIRSTYLE" +#~ msgstr "Folgende SITE-Anweisungen werden unterstützt: HELP DIRSTYLE" +#~ msgid "" +#~ "The function completed successfully, but CompleteToken must be called" +#~ msgstr "" +#~ "Die Funktion wurde erfolgreich ausgeführt, aber CompleteToken muss " +#~ "aufgerufen werden" +#~ msgid "" +#~ "The function completed successfully, but both CompleteToken and this " +#~ "function must be called to complete the context" +#~ msgstr "" +#~ "Die Funktion wurde erfolgreich ausgeführt, aber CompleteToken als auch " +#~ "diese Funktion müssen aufgerufen werden, um den Kontext zu " +#~ "vervollständigen" +#~ msgid "" +#~ "The function completed successfully, but must be called again to complete " +#~ "the context" +#~ msgstr "" +#~ "Die Funktion wurde erfolgreich ausgeführt, muss aber zur " +#~ "Vervollständigung des Kontexts wieder aufgerufen werden" +#~ msgid "The function requested is not supported" +#~ msgstr "Die angeforderte Funktion wird nicht unterstützt" +#~ msgid "The handle specified is invalid" +#~ msgstr "Das angegebene Handle ist ungültig" +#~ msgid "The logon attempt failed" +#~ msgstr "Der Versuch der Anmeldung ist fehlgeschlagen" +#~ msgid "" +#~ "The logon was completed, but no network authority was available. The " +#~ "logon was made using locally known information" +#~ msgstr "" +#~ "Die Anmeldung wurde durchgeführt, aber es war keine Netzwerk-Autorität " +#~ "verfügbar. Die Anmeldung wurde unter Verwendung lokal bekannter " +#~ "Informationen durchgeführt" +#~ msgid "The message or signature supplied for verification has been altered" +#~ msgstr "" +#~ "Die zur Verifizierung übermittelte Botschaft oder Signatur wurde verändert" +#~ msgid "The message received was unexpected or badly formatted." +#~ msgstr "Die empfangene Botschaft war nicht erwartet oder falsch formatiert." +#~ msgid "The message supplied for verification is out of sequence" +#~ msgstr "" +#~ "Die zur Verifizierung übermittelte Botschaft ist außerhalb der Sequenz" +#~ msgid "" +#~ "The per-message Quality of Protection is not supported by the security " +#~ "package" +#~ msgstr "" +#~ "Der Qualitätsschutz pro Botschaft wird vom Sicherheits-Package nicht " +#~ "unterstützt" +#~ msgid "The received certificate has expired." +#~ msgstr "Das empfangene Zertifikat ist abgelaufen." +#~ msgid "The requested security package does not exist" +#~ msgstr "Das angeforderte Sicherheits-Package existiert nicht" +#~ msgid "" +#~ "The security context could not be established due to a failure in the " +#~ "requested quality of service (e.g. mutual authentication or delegation)." +#~ msgstr "" +#~ "Der Sicherheitskontext konnte nicht eingerichtet werden, da Qualität des " +#~ "Service fehlt (z.B. gegenseitige Authentifizierung oder Delegation)." +#~ msgid "The security context does not allow impersonation of the client" +#~ msgstr "Der Sicherheitskontext erlaubt keine Darstellung des Client" +#~ msgid "The security package failed to initialize, and cannot be installed" +#~ msgstr "" +#~ "Das Sicherheits-Package konnte nicht initialisiert werden und kann nicht " +#~ "installiert werden" +#~ msgid "" +#~ "The security package is not able to marshall the logon buffer, so the " +#~ "logon attempt has failed" +#~ msgstr "" +#~ "Das Sicherheits-Package kann den Anmelde-Puffer nicht einrichten, " +#~ "deswegen ist der Versuch der Anmeldung fehlgeschlagen" +#~ msgid "The specified data could not be decrypted." +#~ msgstr "Die angegebenen Daten konnten nicht entschlüsselt werden." +#~ msgid "The specified data could not be encrypted." +#~ msgstr "Die angegebenen Daten konnten nicht verschlüsselt werden." +#~ msgid "The specified target is unknown or unreachable" +#~ msgstr "Das angegebene Ziel ist unbekannt oder nicht erreichbar" +#~ msgid "The string %s does not translate into a valid IP." +#~ msgstr "Zeichenkette %s ergibt keine gültige IP." +#~ msgid "" +#~ "The supplied IP address is not a valid multicast address [224.0.0.0 to " +#~ "239.255.255.255]." +#~ msgstr "" +#~ "Die übermittelte IP-Adresse ist keine gültige Multicast-Adresse " +#~ "[224.0.0.0 bis 239.255.255.255]." +#~ msgid "The supplied message is incomplete. The signature was not verified." +#~ msgstr "" +#~ "Die übermittelte Botschaft ist unvollständig. Die Signatur wurde nicht " +#~ "verifiziert." +#~ msgid "The target principal name is incorrect." +#~ msgstr "Der Ziel-Prinzipalname ist nicht korrekt." +#~ msgid "The token supplied to the function is invalid" +#~ msgstr "Das der Funktion übermittelte Token ist ungültig" +#~ msgid "There is currently no active project." +#~ msgstr "Es gibt momentan kein aktives Projekt." +#~ msgid "There is no LSA mode context associated with this context." +#~ msgstr "Mit diesem Kontext ist kein LSA-Modus-Kontext verknüpft." +#~ msgid "There is no active transaction" +#~ msgstr "Es ist keine Transaktion aktiv" +#~ msgid "" +#~ "There is too many IP addresses in the specified range (%d) to be " +#~ "displayed at design time." +#~ msgstr "" +#~ "Im angegebenen Bereich (%d) gibt es mehr IP-Adressen als zur Entwurfszeit " +#~ "angezeigt werden können." +#~ msgid "This authentication method is already registered with class name %s." +#~ msgstr "" +#~ "Diese Authentifizierungsmethode ist bereits mit Klassennamen %s " +#~ "registriert." +#~ msgid "This function is not supported on Win32." +#~ msgstr "Diese Funktion wird nicht auf Win32 unterstützt." +#~ msgid "This property or method is not implemented in the Open XML Parser" +#~ msgstr "Eigenschaft oder Methode ist nicht im Open XML Parser implementiert" +#~ msgid "Thread" +#~ msgstr "Thread" +#~ msgid "Thread Class Not Specified." +#~ msgstr "Thread-Klasse wurde nicht angegeben." +#~ msgid "Thread Error: %s (%d)" +#~ msgstr "Thread-Fehler: %s (%d)" +#~ msgid "Thread creation error: %s" +#~ msgstr "Fehler beim Erzeugen des Thread: %s" +#~ msgid "Tile &Horizontally" +#~ msgstr "Hori&zontal anordnen" +#~ msgid "Tile Horizontal" +#~ msgstr "Horizontal anordnen" +#~ msgid "Tile Vertical" +#~ msgstr "Vertikal anordnen" +#~ msgid "Time" +#~ msgstr "Uhrzeit" +#~ msgid "TimedOut" +#~ msgstr "TimedOut" +#~ msgid "Timeout occurred waiting for %s to execute" +#~ msgstr "" +#~ "Beim Warten auf die AUsführung von %s ist eine Zeitüberschreitung " +#~ "aufgetreten" +#~ msgid "" +#~ "To add actions to your application simply drag and drop from either " +#~ "Categories or Actions onto an existing ActionBar.\n" +#~ msgstr "" +#~ "Um Akionen zur Applikation hinzuzufügen, ziehen Sie sie einfach mittels " +#~ "Drag&&Drop entweder von den Kategorien oder Aktionen auf ein " +#~ "existierendes ActionBar-Element.\n" +#~ msgid "Toggle" +#~ msgstr "Umschalten" +#~ msgid "Tons" +#~ msgstr "Tonne" +#~ msgid "Too many buttons specified for message box" +#~ msgstr "Bei diesem Meldungsfenster wurden zu viele Schalter angegeben" +#~ msgid "Too many custom variant types have been registered" +#~ msgstr "Es wurden zu viele benutzerdefinierte Variant-Typen registriert" +#~ msgid "Too many levels of remote in path." +#~ msgstr "Zu viele Ebenen von remote in Pfad." +#~ msgid "Too many levels of symbolic links." +#~ msgstr "Zu viele Ebenen von symbolischen Links." +#~ msgid "Too many open files." +#~ msgstr "Zu viele geöffnete Dateien." +#~ msgid "Too many parameters for method %s" +#~ msgstr "Zu viele Parameter für Methode %s" +#~ msgid "Too many parameters in method %s" +#~ msgstr "Zu viele Parameter in Methode %s" +#~ msgid "Too many processes." +#~ msgstr "Zu viele Prozesse." +#~ msgid "Too many references, cannot splice." +#~ msgstr "Zu viele Referenzen; keine Verbindungen möglich." +#~ msgid "Too many users." +#~ msgstr "Zu viele Benutzer." +#~ msgid "Toolb&ars:" +#~ msgstr "&Symbolleisten" +#~ msgid "Toolbars" +#~ msgstr "Symbolleisten" +#~ msgid "Topic Search" +#~ msgstr "Suche über Schlüsselwort" +#~ msgid "Total Response Time:" +#~ msgstr "Antwortzeit, gesamt:" +#~ msgid "Transfer aborted" +#~ msgstr "Transfer abgebrochen" +#~ msgid "Transfer complete" +#~ msgstr "Transfer abgeschlossen" +#~ msgid "Transform failed" +#~ msgstr "Transformation fehlgeschlagen" +#~ msgid "" +#~ "TransformNode most be called using a document node (not a document " +#~ "element) for the source and the stylesheet." +#~ msgstr "" +#~ "TransformNode muss mit einem Dokumentknoten (nicht einem Dokumentelement) " +#~ "für die Quelle und das Stylesheet aufgerufen werden." +#~ msgid "TransformationFile must be specified" +#~ msgstr "TransformationFile muss angegeben werden" +#~ msgid "TreeView Items Editor" +#~ msgstr "TreeView-Eintragseditor" +#~ msgid "" +#~ "Trying to store a string of length %d into a field that can only contain %" +#~ "d" +#~ msgstr "" +#~ "Versuch, String mit der Länge %d in einem Feld zu speichern, das nur %d " +#~ "aufnehmen kann" +#~ msgid "Type" +#~ msgstr "Typ" +#~ msgid "Type cannot be cast as Variant" +#~ msgstr "Typ kann nicht in Variant umgewandelt werden" +#~ msgid "Type mismatch in parameter %d for method %s" +#~ msgstr "Keine Übereinstimmung in Parameter %d für Methode %s" +#~ msgid "Type mismatch in parameter %s" +#~ msgstr "Keine Typübereinstimmung im Parameter %s" +#~ msgid "Type set to %s." +#~ msgstr "Typ auf %s gesetzt." +#~ msgid "UDP Receive Error = 0." +#~ msgstr "UDP Empfangsfehler = 0." +#~ msgid "UKBuckets" +#~ msgstr "UKBuckets" +#~ msgid "UKBushels" +#~ msgstr "Scheffel (UK)" +#~ msgid "UKGallons" +#~ msgstr "Gallone (UK)" +#~ msgid "UKGill" +#~ msgstr "Viertelpinte (UK)" +#~ msgid "UKOunces" +#~ msgstr "Unze (UK)" +#~ msgid "UKPecks" +#~ msgstr "Viertelscheffel (UK)" +#~ msgid "UKPints" +#~ msgstr "Pinte (UK)" +#~ msgid "UKPottle" +#~ msgstr "Pottle (UK)" +#~ msgid "UKQuarts" +#~ msgstr "Quart (UK)" +#~ msgid "UUCP subsystem" +#~ msgstr "UUCP-Subsystem" +#~ msgid "Unable to Find Procedure %s" +#~ msgstr "Prozedur %s nicht gefunden" +#~ msgid "Unable to Load %s" +#~ msgstr "%s kann nicht geladen werden" +#~ msgid "Unable to Open Metadata" +#~ msgstr "Metadaten können nicht geöffnet werden" +#~ msgid "Unable to complete write request, progress halted at %d bytes" +#~ msgstr "" +#~ "Die Schreibanforderung konnte nicht abgeschlossen werden, der Fortschritt " +#~ "wurde bei %d Byte angehalten" +#~ msgid "Unable to create directory \"%s\"." +#~ msgstr "Verzeichnis \"%s\" kann nicht angelegt werden." +#~ msgid "Unable to execute %s" +#~ msgstr "%s kann nicht ausgeführt werden" +#~ msgid "Unable to execute Query" +#~ msgstr "Abfrage kann nicht ausgeführt werden" +#~ msgid "" +#~ "Unable to execute command, wrong connection state;Current connection " +#~ "state: %s." +#~ msgstr "" +#~ "Anweisung kann nicht ausgeführt werden, falscher Verbindungsstatus;" +#~ "aktueller Verbindungsstatus: %s." +#~ msgid "Unable to find a Table of Contents" +#~ msgstr "Inhaltsverzeichnis konnte nicht gefunden werden" +#~ msgid "Unable to initialize compressor" +#~ msgstr "Kompressor kann nicht initialisiert werden" +#~ msgid "Unable to initialize decompressor" +#~ msgstr "Dekompressor kann nicht initialisiert werden" +#~ msgid "Unable to load WSDL File/Location: %s. Error [%s]" +#~ msgstr "WSDL-Datei/-Ort kann nicht geladen werden: %s.\tFehler [%s]" +#~ msgid "Unable to locate form/component, '%s'" +#~ msgstr "Formular/Komponente '%s' nicht gefunden" +#~ msgid "Unable to locate property '%s' on component '%s'" +#~ msgstr "Eigenschaft '%s' in Komponente '%s' nicht gefunden" +#~ msgid "Unable to move %s to %s" +#~ msgstr "%s kann nicht nach %s verschoben werden" +#~ msgid "Unable to not open registry key: %s" +#~ msgstr "Der Registrierungsschlüssel %s kann nicht geöffnet werden" +#~ msgid "Unable to open %s" +#~ msgstr "%s kann nicht geöffnet werden" +#~ msgid "Unable to read directory \"%s\"." +#~ msgstr "Verzeichnis \"%s\" kann nicht gelesen werden." +#~ msgid "" +#~ "Unable to retrieve the URL endpoint for Service/Port '%s'/'%s' from WSDL " +#~ "'%s'" +#~ msgstr "" +#~ "URL-Endpunkt für Service/Port '%s'/'%s' kann nicht von WSDL '%s' gelesen " +#~ "werden" +#~ msgid "Unable to save settings" +#~ msgstr "Einstellungen konnten nicht gespeichert werden" +#~ msgid "Unable to stop client thread" +#~ msgstr "Client-Thread kann nicht angehalten werden" +#~ msgid "Unable to write bitmap" +#~ msgstr "Bitmap kann nicht geschrieben werden" +#~ msgid "Unassigned variant value" +#~ msgstr "Nicht zugewiesener Variant-Wert" +#~ msgid "Unauthorized" +#~ msgstr "Nicht autorisiert" +#~ msgid "Underline" +#~ msgstr "Unterstrichen" +#~ msgid "Undo|Reverts the last action" +#~ msgstr "Rückgängig|Letzte Aktuion rückgängig machen" +#~ msgid "Uneven size in DecodeToStream." +#~ msgstr "Ungleichmäßige Größe in DecodeToStream." +#~ msgid "Uneven size in Encode." +#~ msgstr "Ungleichmäßige Größe in Encode." +#~ msgid "Unexpected characters" +#~ msgstr "Unerwartete Zeichen" +#~ msgid "Unexpected end of string [%s]" +#~ msgstr "Unerwartetes Ende des Strings [%s]" +#~ msgid "Unexpected error occurred executing %s" +#~ msgstr "Bei der Ausführung von %s ist ein Fehler aufgetreten" +#~ msgid "Unexpected message arrived to an interface that is not listening" +#~ msgstr "" +#~ "Eine unerwartete Botschaft kam bei einem Interface an, das nicht " +#~ "empfangsbereit ist." +#~ msgid "Unexpected onError return value" +#~ msgstr "Unerwarteter Rückgabewert von onError" +#~ msgid "Unexpected onStatus return value" +#~ msgstr "Unerwarteter Rückgabewert von onStatus" +#~ msgid "Unexpected operation from %s:%d" +#~ msgstr "Unerwartete Operation von %s:%d" +#~ msgid "Unexpected parameter type" +#~ msgstr "Unerwarteter Parametertyp" +#~ msgid "Unexpected return type" +#~ msgstr "Unerwarteter Rückgabetyp" +#~ msgid "Unexpected script error" +#~ msgstr "Unerwarteter Script-Fehler" +#~ msgid "Unexpected variant error" +#~ msgstr "Unerwarteter Variant-Fehler" +#~ msgid "Unexpected variant or safe array error: %s%.8x" +#~ msgstr "Unerwarteter Fehler bei Variante oder sicherem Array: %s%.8x" +#~ msgid "Unhandled Xerces DOM error (no message available): %d" +#~ msgstr "Unbehandelter Xerces-DOM-Fehler (keine Meldung verfügbar): %d" +#~ msgid "Uninstall File Name is not set" +#~ msgstr "Dateiname für die Deinstallation ist nicht gesetzt" +#~ msgid "Unknown" +#~ msgstr "Unbekannt" +#~ msgid "Unknown Adapter mode: %s" +#~ msgstr "Unbekannter Adaptermodus: %s" +#~ msgid "Unknown Error" +#~ msgstr "Unbekannter Fehler" +#~ msgid "Unknown Error - Can't retrieve plan" +#~ msgstr "Unbekannter Fehler - Plan kann nicht ermittelt werden" +#~ msgid "Unknown FTP listing format" +#~ msgstr "Unbekanntes FTP-Listenformat" +#~ msgid "Unknown Message Part Type." +#~ msgstr "Unbekannter Typ von Botschaftsteil." +#~ msgid "Unknown Response Code" +#~ msgstr "Unbekannter Antwort-Code" +#~ msgid "Unknown SOAPAction %s" +#~ msgstr "Unbekannte SOAP-Aktion %s" +#~ msgid "Unknown Type" +#~ msgstr "Unbekannter Typ" +#~ msgid "Unknown command" +#~ msgstr "Unbekannte Anweisung" +#~ msgid "Unknown conversion family %s" +#~ msgstr "Unbekannte Konvertierungsfamilie %s" +#~ msgid "Unknown conversion type %s" +#~ msgstr "Unkannter Konvertierungstyp %s" +#~ msgid "Unknown credentials use" +#~ msgstr "Verwendung unbekannter Beglaubigung" +#~ msgid "Unknown custom variant type ($%.4x)" +#~ msgstr "Unbekannter benutzerdefinierter Variant-Typ ($%.4x)" +#~ msgid "Unknown datatype \"%s\"" +#~ msgstr "Unbekannter Datentyp \"%s\"" +#~ msgid "Unknown mode" +#~ msgstr "Unbekannter Modus" +#~ msgid "Unknown or illegale facility code" +#~ msgstr "Unbekannter oder ungültiger Facility-Code" +#~ msgid "Unknown or illegale security code" +#~ msgstr "Unbekannter oder ungültiger Sicherheits-Code" +#~ msgid "" +#~ "Unknown or other error: Can not determine owner, other error, or the " +#~ "error can not be revealed." +#~ msgstr "" +#~ "Unbekannter oder anderer Fehler: Der Besitzer oder anderer Fehler kann " +#~ "nicht festgelegt werden oder der Fehler kann nicht angezeigt werden." +#~ msgid "Unknown queue %s" +#~ msgstr "Unbekannte Warteschlange %s" +#~ msgid "Unknown socks error." +#~ msgstr "Unbekannter SOCKS-Fehler." +#~ msgid "Unknown user name" +#~ msgstr "Unbekannter Benutzername" +#~ msgid "Unnamed" +#~ msgstr "Unbenannt" +#~ msgid "Unrecognized IMAP4 Response Header." +#~ msgstr "Nicht erkannter IMAP4-Response-Header." +#~ msgid "" +#~ "Unrecognized POP3 Response Header:\n" +#~ "\"%s\"" +#~ msgstr "" +#~ "Nicht erkannter POP3-Response-Header:\n" +#~ "\"%s\"" +#~ msgid "Unrecognized UUE encoding scheme." +#~ msgstr "Nicht erkannter UUE-Codierungsschema." +#~ msgid "Unrecognized content trasnfer encoding." +#~ msgstr "Nicht erkannte Inhalts-Transfer-Codierung." +#~ msgid "Unrecognized movie format" +#~ msgstr "Unbekanntes Filmformat" +#~ msgid "Unsupported Media Type" +#~ msgstr "Nicht unterstützter Medientyp" +#~ msgid "Unsupported SOAP encodingStyle %s" +#~ msgstr "Nicht unterstützter SOAP-Codierungsstil %s" +#~ msgid "Unsupported authorization scheme." +#~ msgstr "Nicht unterstütztes Autorisierungs-Schema." +#~ msgid "Unsupported calling convention: %s" +#~ msgstr "Nicht unterstützte Aufrufkonvention: %s" +#~ msgid "Unsupported character encoding \"%s\", try using LoadFromFile" +#~ msgstr "" +#~ "Nicht unterstützte Zeichencodierung \"%s\", versuchen Sie LoadFromFile" +#~ msgid "" +#~ "Unsupported hash algorithm. This implementation supports only MD5 " +#~ "encoding." +#~ msgstr "" +#~ "Nicht unterstützter Hash-Algorithmus. Die Implementierung unterstützt nur " +#~ "MD5-Codierung." +#~ msgid "" +#~ "Unsupported object type. You can assign only one of the following types " +#~ "or thir descendants: TStrings, TStream." +#~ msgstr "" +#~ "Nicht unterstützter Objekttyp. Sie können nur einen der folgenden Typen " +#~ "oder deren Nachkommen zuweisen: TStrings, TStream." +#~ msgid "Unsupported transfer mode: \"%s\"" +#~ msgstr "Nicht unterstützter Transfer-Modus: \"%s\"" +#~ msgid "Unsuppported variant type %d" +#~ msgstr "Nicht unterstützter Variant-Typ %d" +#~ msgid "Up one directory" +#~ msgstr "Ein Verzeichnis nach oben" +#~ msgid "" +#~ "Up to
      %0:s\n" +#~ "
        " +#~ msgstr "" +#~ "Bis zu %0:s\n" +#~ "
          " +#~ msgid "" +#~ "Up to root directory\n" +#~ "
            " +#~ msgstr "" +#~ "Bis zu Stammverzeichnis\n" +#~ "
              " +#~ msgid "Update Error - %s" +#~ msgstr "Fehler bei der Aktualisierung - %s" +#~ msgid "Uploaded file expected for field %s" +#~ msgstr "Für Feld %s wird eine gesendete Datei erwartet" +#~ msgid "Use Proxy" +#~ msgstr "Proxy verwenden" +#~ msgid "User logged in, proceed." +#~ msgstr "Benutzer angemeldet, weiter." +#~ msgid "User name okay, need password." +#~ msgstr "Benutzername OK, Passwort wird benötigt." +#~ msgid "User not local, Will forward" +#~ msgstr "Benutzer nicht lokal, wird weitergeleitet" +#~ msgid "UserID not found" +#~ msgstr "Benutzer-ID nicht gefunden" +#~ msgid "UserName" +#~ msgstr "Benutzername" +#~ msgid "Username must not be blank" +#~ msgstr "Benutzername muss angegeben werden" +#~ msgid "Username: " +#~ msgstr "Benutzername: " +#~ msgid "Valid name, no data record (check DNS setup)." +#~ msgstr "Gültiger Name, kein Datensatz (überprüfen Sie das DNS-Setup)." +#~ msgid "Value" +#~ msgstr "Wert" +#~ msgid "Value List editor" +#~ msgstr "Wertlisten-Editor" +#~ msgid "Variable %s is not a container" +#~ msgstr "Variable %s ist kein Container" +#~ msgid "Variable not found: %s" +#~ msgstr "Variable nicht gefunden: %s" +#~ msgid "Variant is empty" +#~ msgstr "Die Variante ist leer" +#~ msgid "Variant operation ran out memory" +#~ msgstr "Speichermangel bei Varinat-Operation" +#~ msgid "Variant or safe array index out of bounds" +#~ msgstr "Variante oder sicherer Array-Index außerhalb des gültigen Bereichs" +#~ msgid "Variant or safe array is locked" +#~ msgstr "Variante oder sicherer Array ist gesperrt" +#~ msgid "Variant overflow" +#~ msgstr "Variant-Überlauf" +#~ msgid "Version %s" +#~ msgstr "Version %s" +#~ msgid "Version 3.0" +#~ msgstr "Version 3.0" +#~ msgid "Version of Transformation File not supported" +#~ msgstr "Version der Umwandlungsdatei wird nicht unterstützt" +#~ msgid "Volume" +#~ msgstr "Volumen" +#~ msgid "WINSOCK DLL Version out of range." +#~ msgstr "Version der WINSOCK-DLL ist außerhalb des gültigen Bereichs." +#~ msgid "WSDL" +#~ msgstr "WSDL" +#~ msgid "WSDL Ports for PortType" +#~ msgstr "WSDL-Ports für PortType" +#~ msgid "WSIL:" +#~ msgstr "WSIL:" +#~ msgid "Warning: warning conditions" +#~ msgstr "Warnung: Warnungszustand" +#~ msgid "Web App Debugger" +#~ msgstr "Web-Anwendungs-Debugger" +#~ msgid "Web App Module Factory already registered." +#~ msgstr "Modul-Factory für Web-Anwendung bereits registriert." +#~ msgid "Web Application Debugger" +#~ msgstr "Debugger für Web-Anwendungen" +#~ msgid "Web Module Factory already registered" +#~ msgstr "Web-Modul-Factory bereits registriert." +#~ msgid "Web Page does not provide content" +#~ msgstr "Web-Seite enthält keinen Inhalt" +#~ msgid "Web Page does not support redirect" +#~ msgstr "Web-Seite unterstützt Umleitungen nicht" +#~ msgid "Web Page not found: %s" +#~ msgstr "Web-Seite nicht gefunden: %s" +#~ msgid "WebAppModule" +#~ msgstr "WebAppModule" +#~ msgid "WebService Listing" +#~ msgstr "WebService-Liste" +#~ msgid "WebService Listing Administrator" +#~ msgstr "Administrator für WebService-Listen" +#~ msgid "WebSnap" +#~ msgstr "WebSnap" +#~ msgid "WebSnap Application" +#~ msgstr "WebSnap-Anwendung" +#~ msgid "WebSnap Data Module" +#~ msgstr "WebSnap-Datenmodul" +#~ msgid "WebSnap Page Module" +#~ msgstr "WebSnap-Seitenmodul" +#~ msgid "Weeks" +#~ msgstr "Woche" +#~ msgid "Welcome to the INDY SMTP Server" +#~ msgstr "Willkommen beim INDY SMTP-Server" +#~ msgid "White" +#~ msgstr "Weiß" +#~ msgid "WideString index out of bounds" +#~ msgstr "WideString-Index außerhalb des gültigen Bereichs" +#~ msgid "Window" +#~ msgstr "Fenster" +#~ msgid "Window Background" +#~ msgstr "Fensterhintergrund" +#~ msgid "Window Frame" +#~ msgstr "Fensterrahmen" +#~ msgid "Window Text" +#~ msgstr "Fenstertext" +#~ msgid "Winshoes LPD Server %s " +#~ msgstr "Winshoes LPD-Server %s " +#~ msgid "Winsock Initialization Error." +#~ msgstr "Fehler bei der Winsock-Initialisierung." +#~ msgid "Winsock not loaded yet." +#~ msgstr "Winsock noch nicht geladen." +#~ msgid "Winsock stack" +#~ msgstr "Winsock-Stack" +#~ msgid "Would you like to reset to the default Priority Schedule?" +#~ msgstr "Wollen Sie auf die Standard-Prioritätenverteilung zurücksetzen?" +#~ msgid "XDR to XML Schema Translator (.xdr <-> .xsd)" +#~ msgstr "Übersetzer XDR nach XML-Schema (.xdr <-> .xsd)" +#~ msgid "XML Parse Error:\n" +#~ msgstr "XML-Auswertungsfehler:\n" +#~ msgid "XML files (*.xml)|*.xml" +#~ msgstr "XML-Dateien (*.xml)|*.xml" +#~ msgid "XMLData to XML Schema Translator (.xml -> .xsd)" +#~ msgstr "Übersetzer XMLData nach XML-Schema (.xml -> .xsd)" +#~ msgid "XMLDataFile must be specified" +#~ msgstr "XMLDataFile muss angegeben werden" +#~ msgid "XP Style" +#~ msgstr "XP-Attribut" +#~ msgid "XTR files (*.xtr)|*.xtr" +#~ msgstr "XTR-Dateien(*.xtr)|*.xtr" +#~ msgid "Yards" +#~ msgstr "Yard" +#~ msgid "Year portion of date too large for conversion" +#~ msgstr "Die Jahreszahl im Datumswert ist zu groß für eine Konvertierung" +#~ msgid "Years" +#~ msgstr "Jahr" +#~ msgid "Yellow" +#~ msgstr "Gelb" +#~ msgid "You are not allowed to delete this item" +#~ msgstr "Sie dürfen diesen Eintrag nicht löschen" +#~ msgid "You cannot send a message while you are still waiting for an answer" +#~ msgstr "" +#~ "Sie können keine Botschaft schicken, während Sie auf eine Antwort warten." +#~ msgid "You cannot set %s while the HL7 Component is working" +#~ msgstr "Sie können %s nicht setzen, während die HL7-Komponente arbeitet" +#~ msgid "You must chain this component to another I/O Handler before using it" +#~ msgstr "" +#~ "Sie müssen diese Komponenten vor ihrer Verwendung an einen anderen I/O-" +#~ "Handler binden" +#~ msgid "ZLib error: target buffer may be too small" +#~ msgstr "Zlib-Fehler: Zielpuffer könnte zu klein sein" +#~ msgid "abort job" +#~ msgstr "Job abbrechen" +#~ msgid "address" +#~ msgstr "Adresse" +#~ msgid "bmp" +#~ msgstr "bmp" +#~ msgid "by DNSName [127.0.0.1] running Indy SMTP" +#~ msgstr "nach DNSName [127.0.0.1] ausgeführt wird Indy SMTP" +#~ msgid "cbxFields" +#~ msgstr "cbxFelder" +#~ msgid "cbxGenerators" +#~ msgstr "cbxGeneratoren" +#~ msgid "clock daemon (1)" +#~ msgstr "Uhrzeit-Daemon (1)" +#~ msgid "clock daemon (2)" +#~ msgstr "Uhrzeit-Daemon (2)" +#~ msgid "closing connection" +#~ msgstr "Verbindung wird geschlossen" +#~ msgid "command must be either USER or QUIT" +#~ msgstr "Anweisung muss entweder USER oder QUIT sein" +#~ msgid "command not recognized" +#~ msgstr "Anweisung nicht erkannt" +#~ msgid "connected with %s" +#~ msgstr "Verbunden mit %s" +#~ msgid "dbExpress Error: Application is not licensed to use this feature" +#~ msgstr "dbExpress-Fehler: Anwendung ist für diese Funktion nicht lizenziert" +#~ msgid "dbExpress Error: Duplicate Transaction ID" +#~ msgstr "dbExpress-Fehler: Doppelte Transaktions-ID" +#~ msgid "dbExpress Error: Insufficient Memory for Operation" +#~ msgstr "dbExpress-Fehler: Nicht genügend Speicher für diese Operation" +#~ msgid "dbExpress Error: Invalid Data Translation" +#~ msgstr "dbExpress-Fehler: Ungültige Übersetzung" +#~ msgid "dbExpress Error: Invalid Field Type" +#~ msgstr "dbExpress-Fehler: Ungültiger Feldtyp" +#~ msgid "dbExpress Error: Invalid Handle" +#~ msgstr "dbExpress-Fehler: Ungültiges Handle" +#~ msgid "dbExpress Error: Invalid Length" +#~ msgstr "dbExpress-Fehler: Ungültige Länge" +#~ msgid "dbExpress Error: Invalid Parameter" +#~ msgstr "dbExpress-Fehler: Ungültiger Parameter" +#~ msgid "dbExpress Error: Invalid Precision" +#~ msgstr "dbExpress-Fehler: Ungültige Genauigkeit" +#~ msgid "dbExpress Error: Invalid Time" +#~ msgstr "dbExpress-Fehler: Ungültiger Zeitwert" +#~ msgid "dbExpress Error: Invalid Transaction ID" +#~ msgstr "dbExpress-Fehler: Ungültige Transaktions-ID" +#~ msgid "dbExpress Error: Invalid Transaction Isolation Level" +#~ msgstr "dbExpress-Fehler: Ungültige Ebene für Transaktionsisolation" +#~ msgid "dbExpress Error: Invalid Username/Password" +#~ msgstr "dbExpress-Fehler: Ungültiger Wert für Anwendername oder Passwort" +#~ msgid "dbExpress Error: Local Transaction already active" +#~ msgstr "dbExpress-Fehler: Lokale Transaktion bereits aktiv" +#~ msgid "dbExpress Error: Multiple Transactions not Enabled" +#~ msgstr "dbExpress-Fehler: Mehrfach-Transaktionen nicht aktiviert" +#~ msgid "dbExpress Error: Operation Not Supported" +#~ msgstr "dbExpress-Fehler: Die Operation wird nicht unterstützt" +#~ msgid "dbExpress Error: Parameter Not Set" +#~ msgstr "dbExpress-Fehler: Parameter ist nicht gesetzt" +#~ msgid "dbExpress Error: Parameter/Column out of Range" +#~ msgstr "dbExpress-Fehler: Parameter/Spalte außerhalb des gültigen Bereichs" +#~ msgid "dbExpress Error: Result set at EOF" +#~ msgstr "dbExpress-Fehler: Ergebnismenge am Dateiende" +#~ msgid "ddd, dd mmm yyyy hh:mm:ss" +#~ msgstr "ttt, tt mmm jjjj hh:mm:ss" +#~ msgid "frmGeneratorEditor" +#~ msgstr "frmGeneratorEditor" +#~ msgid "goColMoving is not a supported option" +#~ msgstr "goColMoving wird nicht unterstützt" +#~ msgid "http://www.nevrona.com/indy/" +#~ msgstr "http://www.nevrona.com/indy/" +#~ msgid "kernel messages" +#~ msgstr "Kernel-Botschaften" +#~ msgid "line" +#~ msgstr "Zeile" +#~ msgid "line printer subsystem" +#~ msgstr "Zeilendrucker-Untersystem" +#~ msgid "lines" +#~ msgstr "Zeilen" +#~ msgid "local use 0 (local0)" +#~ msgstr "Lokale Verwendung 0 (local0)" +#~ msgid "local use 1 (local1)" +#~ msgstr "Lokale Verwendung 1 (local1)" +#~ msgid "local use 2 (local2)" +#~ msgstr "Lokale Verwendung 2 (local2)" +#~ msgid "local use 3 (local3)" +#~ msgstr "Lokale Verwendung 3 (local3)" +#~ msgid "local use 4 (local4)" +#~ msgstr "Lokale Verwendung 4 (local4)" +#~ msgid "local use 5 (local5)" +#~ msgstr "Lokale Verwendung 5 (local5)" +#~ msgid "local use 6 (local6)" +#~ msgstr "Lokale Verwendung 6 (local6)" +#~ msgid "local use 7 (local7)" +#~ msgstr "Lokale Verwendung 7 (local7)" +#~ msgid "log alert" +#~ msgstr "Protokollalarm" +#~ msgid "log audit" +#~ msgstr "Protokollüberprüfung" +#~ msgid "mail system" +#~ msgstr "Mail-System" +#~ msgid "messages generated internally by syslogd" +#~ msgstr "Botschaften, die intern von syslogd generiert werden" +#~ msgid "method not supported" +#~ msgstr "Methode nicht unterstützt" +#~ msgid "network news subsystem" +#~ msgstr "Netzwerknachrichtensystem" +#~ msgid "open" +#~ msgstr "&Ausführen..." +#~ msgid "security/authorization messages (1)" +#~ msgstr "Sicherheits-/Autorisierungsbotschaften (1)" +#~ msgid "security/authorization messages (2)" +#~ msgstr "Sicherheits-/Autorisierungsbotschaften (2)" +#~ msgid "server not responding" +#~ msgstr "Server antwortet nicht." +#~ msgid "sigaction call failed" +#~ msgstr "sigaction call failed" +#~ msgid "system daemons" +#~ msgstr "System-Daemone" +#~ msgid "txt" +#~ msgstr "txt" +#~ msgid "unknown" +#~ msgstr "Unbekannt" +#~ msgid "user-level messages" +#~ msgstr "Botschaften auf Benutzerebene" +#~ msgid "username" +#~ msgstr "Benutzername" +#~ msgid "varDate type not supported" +#~ msgstr "Typ varDate wird nicht unterstützt" +#~ msgid "varDispatch type not supported" +#~ msgstr "Typ varDispatch wird nicht unterstützt" +#~ msgid "varError type not supported" +#~ msgstr "Typ varError wird nicht unterstützt" +#~ msgid "varVariant type not supported" +#~ msgstr "Typ varVariant wird nicht unterstützt" +#~ msgid "xml" +#~ msgstr "xml" +#~ msgid "xtr" +#~ msgstr "xtr" + diff --git a/win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po b/win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po new file mode 100644 index 000000000..8032db57e --- /dev/null +++ b/win32/gui-2/locale/de/LC_MESSAGES/gpsbabel.po @@ -0,0 +1,398 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel command line program\n" +"POT-Creation-Date: 2005-11-19 01:14\n" +"PO-Revision-Date: 2006-10-30 18:29+0100\n" +"Last-Translator: Olaf Klein \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2.1\n" +"Language-Team: \n" +"X-Poedit-SourceCharset: iso-8859-1\n" +"X-Poedit-Language: German\n" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "Zeitdifferent zwischen Barograph und GPS (ganzz. Sekunden oder 'auto')" + +msgid "(USR input) Break segments into separate tracks" +msgstr "USR Eingabe: Segmente in seperate Tracks aufteilen" + +msgid "(USR output) Merge into one segmented track" +msgstr "USR-Ausgabe: zu einem segmentierten Track zusammenfassen" + +msgid "Ad-hoc closed icon name" +msgstr "Icon allgemein für \"geschlossen\"" + +msgid "Ad-hoc open icon name" +msgstr "Icon allgemein für \"offen\"" + +msgid "Allow whitespace synth. shortnames" +msgstr "Erlaube Leerzeichen in Kurznamen" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "Absolute Höhenangaben (nicht bodenverbunden)" + +msgid "Append icon_descr to description" +msgstr "Erweitere Beschreibung um Symbolbeschreibung" + +msgid "Base URL for link tag in output" +msgstr "Basis-URL für Verknüpfungseintrag " + +msgid "Basename prepended to URL on output" +msgstr "Basis-Adresse für erzeugte URL's" + +msgid "Category name (Cache)" +msgstr "Kategoriename (Cache)" + +msgid "Category number to use for written waypoints" +msgstr "Benutze Kategorie # beim Schreiben von Wegpunkten (1..16)" + +msgid "Color for lines or mapnotes" +msgstr "Farbe für Linien oder Kartenangaben" + +msgid "Command unit to power itself down" +msgstr "Gerät im Anschluß abschalten" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "Komplettiere Tracks ohne Datumsangaben mit Datum ... (YYYYMMDD)" + +msgid "Create waypoints from geocache log entries" +msgstr "Erzeuge Wegpunkte aus Geocache Log-Einträgen" + +msgid "Database name" +msgstr "Interner Name für die Palm/OS Datenbank" + +msgid "Database name (filename)" +msgstr "Datenbankname (Dateiname)" + +msgid "Datum (default=NAD27)" +msgstr "GPS-Datum (Vorgabe: NAD27)" + +msgid "Days after which points are considered old" +msgstr "Anzahl an Tagen, nach denen Punkte als alt betrachtet werden" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "Pause (in Sekunden) zwischen Zeilengruppen" + +msgid "Default category on output (1..16)" +msgstr "Standard Kategorie (1..16)" + +msgid "Default icon name" +msgstr "Standard Symbol" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "Vorgabegeschwindigkeit (Knoten/h)" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "Schreibe Gradangaben in 'ddd', 'dmm' (Vorgabe) oder 'dms' (Gitter)" + +msgid "Delete all waypoints" +msgstr "Lösche alle Wegpunkte" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "Zeige Beschriftung bei Track- und Routenpunkten (Vorgabe: 1)" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "Entfernungsangaben [m=Metrisch, s=Statute]" + +msgid "Do not add geocache data to description" +msgstr "Keine Geocache-Daten zur Beschreibung hinzufügen" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "Zeichne eine Verbindungslinie vom Trackpunkt zum Erdboden" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "Lösche versteckte Wegpunkte (automatisch berechnete Routenpunkte)" + +msgid "Encrypt hints using ROT13" +msgstr "Verschlüsselung mit ROT13" + +msgid "Encrypt hints with ROT13" +msgstr "Verschlüsselung mit ROT13" + +msgid "Erase device data after download" +msgstr "Nach Download Daten auf dem Gerät löschen" + +msgid "Export linestrings for tracks and routes" +msgstr "Exportiere Linendaten (linestrings) für Tracks und Routen (Vorgabe: JA)" + +msgid "Export placemarks for tracks and routes" +msgstr "Exportiere Markierungen für Tracks und Routen" + +msgid "Full path to XCSV style file" +msgstr "Pfad zur 'XCSV-Style'-Datei" + +msgid "Generate file with lat/lon for centering map" +msgstr "Erzeuge Datei mit Breiten- und Längengradwerten (für Kartenzentrierung)" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "Gebe Wegpunkten/Routenpunkten diesen Radius " + +msgid "GPS datum (def. WGS 84)" +msgstr "GPS-Datum (Vorgabe: WGS 84)" + +msgid "Height in pixels of map" +msgstr "Kartenhöhe in Pixel" + +msgid "Ignore event marker icons" +msgstr "Ignoriere Symbole vor Ereignismarkierungen" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "Erweiterte Daten in Trackpoints mit einbeziehen (Vorgabe = 1)" + +msgid "Include groundspeak logs if present" +msgstr "Groundspeak Log's beifügen (wenn vorhandan)" + +msgid "Include only via stations in route" +msgstr "Übernehme nur Stationspunkte ('viastations') der Route" + +msgid "Include short name in bookmarks" +msgstr "Übernehme Kurznamen in Lesezeichen" + +msgid "Index of name field in .dbf" +msgstr "Index des Namensfeldes innerhalb der .dbf" + +msgid "Index of route (if more the one in source)" +msgstr "Index des Route (falls mehrere im Eingabeformat)" + +msgid "Index of route to write (if more the one in source)" +msgstr "Routen-Index (wenn mehrere vorhanden)" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "Route oder Track-Index (wenn mehrere vorhanden)" + +msgid "Index of track (if more the one in source)" +msgstr "Index des Tracks (falls mehrere im Eingabeformat)" + +msgid "Index of track to write (if more the one in source)" +msgstr "Track-Index (wenn mehrere vorhanden)" + +msgid "Index of URL field in .dbf" +msgstr "Index der URL innerhalb der .dbf" + +msgid "Infrastructure closed icon name" +msgstr "Icon \"Komplex (Infrastruktur) geschlossen\"" + +msgid "Infrastructure open icon name" +msgstr "Icon \"Komplex (Infrastruktur) offen\"" + +msgid "Keep turns if simplify filter is used" +msgstr "Erhalte Abbiegungen bei Benutzung des Simplify-Filters (Vereinfachen)" + +msgid "Length of generated shortnames" +msgstr "Maximale Länge der generierten Kurznamen" + +msgid "Length of generated shortnames (default 16)" +msgstr "Maximale Länge der zu generierten Kurznamen" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "Linienfarbe (hex. Angabe in Form AABBGGRR)" + +msgid "Make synth. shortnames unique" +msgstr "Eindeutige Kurznamen erzeugen" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "Generiere TRK-Datei in MapSend-Version # (3,4)" + +msgid "Margin for map. Degrees or percentage" +msgstr "Begrenzung der Karte (in Grad oder Prozent)" + +msgid "Marker type for new points" +msgstr "Markierungstyp für neue Punkte" + +msgid "Marker type for old points" +msgstr "Markierungstyp für alte Punkte" + +msgid "Marker type for unfound points" +msgstr "Markierungstyp für nicht gefundene Punkte" + +msgid "Max length of waypoint name to write" +msgstr "Max. Länge der zu schreibenden Wegpunktnamen" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "Maximale Anzahl an Kommentaren für die Ausgabe" + +msgid "Max shortname length when used with -s" +msgstr "Maximale Länge der generierten Kurznamen" + +msgid "Max synthesized shortname length" +msgstr "Maximale Länge der generierten Kurznamen" + +msgid "Merge output with existing file" +msgstr "Ausgabe in existierende Datei einfügen" + +msgid "Name of the 'unassigned' category" +msgstr "Name der 'unassigned'-Kategorie" + +msgid "New name for the route" +msgstr "Name der neuen Route" + +msgid "No separator lines between waypoints" +msgstr "keine Trennlinien zwischen den Wegpunkten" + +msgid "No whitespace in generated shortnames" +msgstr "Leerzeichen in Kurznamen unterdrücken" + +msgid "Non-stealth encrypted icon name" +msgstr "Sichtbar verschlüsselter Symbolname" + +msgid "Non-stealth non-encrypted icon name" +msgstr "Sichtbar und unverschlüsselter Symbolname" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "Baudrate (Vorgabe: 4800)" + +msgid "Omit Placer name" +msgstr "Placername auslassen" + +msgid "Only read turns; skip all other points" +msgstr "Lese nur Abbiegungen und ignoriere alle sonstigen Punkte" + +msgid "Path to HTML style sheet" +msgstr "Pfad zum HTML-Style-Sheet" + +msgid "Precision of coordinates" +msgstr "Präzision der Koordinaten (Anzahl Nachkommastellen)" + +msgid "Radius for circles" +msgstr "Kreisradius" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "Erdradius in Meter (Vorgabe: 6371000 Meter)" + +msgid "Read control points as waypoint/route/none" +msgstr "Lese Kontrollpunkte als Wegpunkt/Route/nichts" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "Datumsformat für Ein-/Ausgabe (z.B. DDMMYYYY)" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "Datumsformat (z.B. DD.MM.YYYY)" + +msgid "Read/write GPGGA sentences" +msgstr "Schreibe/Lese GPGGA Sequenzen" + +msgid "Read/write GPGSA sentences" +msgstr "Schreibe/Lese GPGSA Sequenzen" + +msgid "Read/write GPRMC sentences" +msgstr "Schreibe/Lese GPRMC Sequenzen" + +msgid "Read/write GPVTG sentences" +msgstr "Schreibe/Lese GPVTG Sequenzen" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "Zeitformat (z.B. HH:mm:ss xx)" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "Behalte höchstens diese Anzahl an Positionspunkten (0 = kein Limit)" + +msgid "Return current position as a waypoint" +msgstr "Übertrage aktuelle Position als Wegpunkt" + +msgid "Road type changes" +msgstr "Straßentyp-Wechsel" + +msgid "Shortname is MAC address" +msgstr "Kurzname ergibt sich aus MAC-Adresse" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "Übertragungsrate des seriellen Ports in Bits/Sekunde (Vorgabe: baud=4800)" + +msgid "Split input into separate files" +msgstr "Teile gelesene Daten in seperate Dateien" + +msgid "Split into multiple routes at turns" +msgstr "Route an Abbiegungen teilen" + +msgid "Stealth encrypted icon name" +msgstr "Unsichtbar verschlüsselter Symbolname" + +msgid "Stealth non-encrypted icon name" +msgstr "Unsichtbarer unverschlüsselter Symbolname" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "Trennzeichen für zusammengefügte Adressfelder (Vorgabe: \", \")" + +msgid "Suppress labels on generated pins" +msgstr "Unterdücke Kennzeichnung für erzeugte Pins" + +msgid "Suppress retired geocaches" +msgstr "Unterdrücke zurückgezogene (?) Geocaches" + +msgid "Suppress separator lines between waypoints" +msgstr "Keine Trennlinien zwischen den Wegpunkten" + +msgid "Suppress use of handshaking in name of speed" +msgstr "Kein 'Handshaking' (im Namen der Geschwindigkeit)" + +msgid "Suppress whitespace in generated shortnames" +msgstr "Keine Leerzeichen in Kurznamen" + +msgid "Symbol to use for point data" +msgstr "Symbol für Punkte" + +msgid "Synthesize track times" +msgstr "Erzeuge Tracknamen" + +msgid "Target GPX version for output" +msgstr "Schreibe in GPX-Version (1.0 oder 1.1)" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "Temperatureinheit [c=Celsius, F=Fahrenheit]" + +msgid "The icon description is already the marker" +msgstr "Die Symbolbeschreibung ist bereits die Markierung" + +msgid "Type of .an1 file" +msgstr ".an1 Dateityp" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "Höhenangaben in Fuß oder Meter ('f' oder 'm')" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "Einheit innerhalb von Kommentaren ( 's'tatute oder 'm'etrisch)" + +msgid "UPPERCASE synth. shortnames" +msgstr "Erzeuge Kurznamen in Großbuchstaben" + +msgid "Use depth values on output (default is ignore)" +msgstr "Tiefenangaben mit ausgeben (normalerweise ausgeschaltet)" + +msgid "Use proximity values on output (default is ignore)" +msgstr "Benutze Proximity-Werte bei der Ausgabe (Vorgabe: NEIN)" + +msgid "Use shortname instead of description" +msgstr "Benutze den Kurznamen anstelle der Beschreibung" + +msgid "Version of gdb file to generate (1,2)" +msgstr "GDB-Version (1 oder 2)" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "Schreibe MapSource Datei in Version ... (3,4 oder 5)" + +msgid "Waypoint background color" +msgstr "Wegpunkt Hintergrundfarbe" + +msgid "Waypoint foreground color" +msgstr "Wegpunkt Vordergrundfarbe" + +msgid "Waypoint type" +msgstr "Wegpunkt Typ" + +msgid "Width in pixels of map" +msgstr "Kartenbreite in Pixel" + +msgid "Width of lines, in pixels" +msgstr "Linienhöhe in Pixel" + +msgid "Write timestamps with offset x to UTC time" +msgstr "Schreibe Zeitstempel relativ zur UTC + x" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "Erzeuge Tracks ohne Titel (kompatibel zu \"Carto Exploreur\")" + +msgid "Zoom level to reduce points" +msgstr "Vergrößerungsfakter um Punkte zu unterdrücken" + diff --git a/win32/gui-2/locale/fr/LC_MESSAGES/default.po b/win32/gui-2/locale/fr/LC_MESSAGES/default.po new file mode 100644 index 000000000..dbd7cd0e1 --- /dev/null +++ b/win32/gui-2/locale/fr/LC_MESSAGES/default.po @@ -0,0 +1,904 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabelGUI-2\n" +"POT-Creation-Date: 2005-09-22 23:44\n" +"PO-Revision-Date: 2006-11-01 20:06+0100\n" +"Last-Translator: Lilian Morinon \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2\n" +"Language-Team: Utagawa VTT \n" +"X-Poedit-Language: French\n" +"X-Poedit-SourceCharset: utf-8\n" +"Plural-Forms: s\n" + +#. frmAbout..Caption +#: about.dfm:5 +msgid "About" +msgstr "A propos" + +#. frmAbout..pnClient..pnCenter..lbHint1..Caption +#: about.dfm:76 +msgid "This program is part of the GPSBabel project, hosted on" +msgstr "Ce programme fait partie du projet GPSBabel, hébergé sur" + +#. frmAbout..pnClient..pnCenter..lbVersion..Caption +#: about.dfm:84 +#: about.pas:80 +msgid "Version" +msgstr "Version" + +#. frmAbout..pnClient..pnCenter..lbTranslators..Caption +#: about.dfm:91 +msgid "Translations" +msgstr "Traductions" + +#. frmAbout..pnClient..pnCenter..lbURL..Caption +#: about.dfm:98 +msgid "www.gpsbabel.org" +msgstr "www.gpsbabel.org" + +#. frmAbout..pnClient..pnCenter..lbCopyRight..Caption +#: about.dfm:114 +msgid "Copyright (C) 2005,2006 Olaf Klein (o.b.klein@gpsbabel.org)" +msgstr "" + +#. frmAbout..pnClient..pnCenter..lbMoreInfo..Caption +#: about.dfm:121 +msgid "Find more info at" +msgstr "Plus d'infos sur" + +#. frmAbout..pnClient..pnCenter..stDescription..Caption +#: about.dfm:149 +msgid "The frontend for GPSBabel command line program" +msgstr "L'interface graphique de GPSBabel" + +#. frmAbout..pnClient..pnCenter..stLicense..Caption +#: about.dfm:163 +msgid "THIS SOFTWARE MAY ONLY BE LICENSED FREE OF CHARGE" +msgstr "Ce prgramme ne peut être utilisé que sous license gratuite" + +#. frmAbout..pnClient..pnCenter..btnNewLanguage..Caption +#: about.dfm:192 +msgid "Adding a new language" +msgstr "Ajouter une nouvelle langue" + +#. frmFilter..Caption +#: filter.dfm:6 +msgid "Filter" +msgstr "Filtre" + +#. frmFilter..gbTracks..Caption +#. frmMain..pnBottom..cbTracks..Caption +#: filter.dfm:31 +#: main.dfm:581 +msgid "&Tracks" +msgstr "&Traces" + +#. frmFilter..gbTracks..lbTimePlusMinus..Caption +#: filter.dfm:39 +#: about.pas:87 +#: about.pas:88 +#: about.pas:89 +msgid "by" +msgstr "par" + +#. frmFilter..gbTracks..lbTimeDays..Caption +#: filter.dfm:46 +msgid "day(s), " +msgstr "jour(s)," + +#. frmFilter..gbTracks..lbTimeHours..Caption +#: filter.dfm:53 +msgid "hour(s), " +msgstr "heure(s)" + +#. frmFilter..gbTracks..lbTimeMinutes..Caption +#: filter.dfm:60 +msgid "minute(s)," +msgstr "minute(s)" + +#. frmFilter..gbTracks..lbTimeSeconds..Caption +#: filter.dfm:67 +msgid "second(s)" +msgstr "seconde(s)" + +#. frmFilter..gbTracks..cbTrackTitle..Hint +#: filter.dfm:74 +msgid "Title for new tracks" +msgstr "Titres des nouvelles traces" + +#. frmFilter..gbTracks..cbTrackTitle..Caption +#: filter.dfm:76 +msgid "Tit&le" +msgstr "Tit&re" + +#. frmFilter..gbTracks..cbTrackSplit..Hint +#: filter.dfm:95 +msgid "Split track into several tracks depending on date of trackpoint" +msgstr "Scinder la trace en plusieurs traces en fonction de la date des points" + +#. frmFilter..gbTracks..cbTrackSplit..Caption +#: filter.dfm:96 +msgid "&Split" +msgstr "&Scinder" + +#. frmFilter..gbTracks..cbTrackTime..Hint +#: filter.dfm:104 +msgid "Shift all tracks" +msgstr "Inverser toutes les traces" + +#. frmFilter..gbTracks..cbTrackTime..Caption +#: filter.dfm:105 +msgid "&Move" +msgstr "&Déplacer" + +#. frmFilter..gbTracks..cbTrackStart..Hint +#: filter.dfm:197 +msgid "Take only trackpoints starting at" +msgstr "Utiliser seulement les points commençant à" + +#. frmFilter..gbTracks..cbTrackStart..Caption +#: filter.dfm:198 +msgid "Start at" +msgstr "Commencer à" + +#. frmFilter..gbTracks..cbTrackStop..Caption +#: filter.dfm:237 +msgid "stop at" +msgstr "Arrêter à" + +#. frmFilter..gbTracks..cbTrackPack..Hint +#: filter.dfm:276 +msgid "Pack all tracks into one track (No duplicate timestamps)" +msgstr "Fusionner toutes les traces en une seule (pas de duplication de l'horodatage)" + +#. frmFilter..gbTracks..cbTrackPack..Caption +#: filter.dfm:277 +msgid "&Pack (or)" +msgstr "&Fusionner (ou)" + +#. frmFilter..gbTracks..cbTrackMerge..Hint +#: filter.dfm:286 +msgid "Merge all tracks into one track" +msgstr "Fusionner toutes les traces en une seule" + +#. frmFilter..gbTracks..cbTrackMerge..Caption +#: filter.dfm:287 +msgid "Merge" +msgstr "Fusionner" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Hint +#: filter.dfm:296 +msgid "Shift start/stop by local timezone offset" +msgstr "Décaler le début/fin en fonction du décalage horaire local" + +#. frmFilter..gbTracks..cbTrackRangeTimeZone..Caption +#: filter.dfm:297 +msgid "TZ" +msgstr "TZ" + +#. frmFilter..gbTracks..cbTrackFixes..Hint +#: filter.dfm:306 +msgid "Synthesize GPS fixes (PPS, DGPS, 3D, 2D)" +msgstr "" + +#. frmFilter..gbTracks..cbTrackFixes..Caption +#: filter.dfm:307 +msgid "GPS fixes" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Hint +#: filter.dfm:315 +msgid "Synthesize course values" +msgstr "" + +#. frmFilter..gbTracks..cbTrackCourse..Caption +#: filter.dfm:316 +msgid "Course" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSpeed..Hint +#: filter.dfm:324 +msgid "Synthesize speed values" +msgstr "" + +#. frmFilter..gbTracks..cbTrackSpeed..Caption +#: filter.dfm:325 +msgid "Speed" +msgstr "Vitesse" + +#. frmFilter..gbRoutes..Caption +#: filter.dfm:335 +msgid "&Routes && Tracks" +msgstr "&Routes && Traces" + +#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption +#: filter.dfm:343 +msgid "limit to" +msgstr "limiter à" + +#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption +#: filter.dfm:351 +msgid "Points" +msgstr "Points" + +#. frmFilter..gbRoutes..cbRouteSimplify..Hint +#: filter.dfm:358 +msgid "Simplify routes and tracks by limited number of points" +msgstr "Simplifier les routes et traces en limitant le nombre de points" + +#. frmFilter..gbRoutes..cbRouteSimplify..Caption +#: filter.dfm:359 +msgid "Simplify" +msgstr "Simplifier" + +#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint +#: filter.dfm:368 +msgid "Upper limit of points for routes and tracks" +msgstr "Limite maximum du nombre de points pour les routes et traces" + +#. frmFilter..gbRoutes..cbReverse..Hint +#: filter.dfm:390 +msgid "Reverse routes and tracks" +msgstr "Inverser les routes et les traces" + +#. frmFilter..gbRoutes..cbReverse..Caption +#: filter.dfm:391 +msgid "Reverse" +msgstr "Inverser" + +#. frmFilter..pnBottom..btnOK..Caption +#: filter.dfm:408 +msgid "OK" +msgstr "OK" + +#. frmFilter..pnBottom..BitBtn1..Caption +#: filter.dfm:444 +msgid "File based filters" +msgstr "Filtres de fichiers" + +#. frmFilter..gbWaypoints..Caption +#. frmMain..pnBottom..cbWaypoints..Caption +#: filter.dfm:473 +#: main.dfm:555 +msgid "&Waypoints" +msgstr "&Waypoints" + +#. frmFilter..gbWaypoints..lbWayptRadiusLat..Caption +#: filter.dfm:482 +msgid "Latitude" +msgstr "Latitude" + +#. frmFilter..gbWaypoints..lbWayptRadiusLon..Caption +#: filter.dfm:490 +msgid "Longitude" +msgstr "Longitude" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint +#: filter.dfm:498 +msgid "Merge waypoints with duplicate locations" +msgstr "Fusionner les waypoints avec les positions en doublon" + +#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption +#: filter.dfm:499 +msgid "locations" +msgstr "positions" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint +#: filter.dfm:508 +msgid "Merge waypoints with duplicate \"short name\"" +msgstr "Fusionner les waypoints avec les doublons \"short name\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption +#: filter.dfm:509 +msgid "\"short names\"" +msgstr "\"noms courts\"" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint +#: filter.dfm:518 +msgid "Merge waypoints separated by less then" +msgstr "Fusionner les waypoints séparé par moins de" + +#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption +#: filter.dfm:519 +msgid "Position" +msgstr "Position" + +#. frmFilter..gbWaypoints..cbWayptSort..Hint +#: filter.dfm:547 +msgid "Sort waypoints by \"short name\" or by description" +msgstr "Trier les waypoints par \"short name\" ou par description" + +#. frmFilter..gbWaypoints..cbWayptSort..Caption +#: filter.dfm:548 +msgid "Sort" +msgstr "Trier" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint +#: filter.dfm:556 +msgid "Merge duplicate waypoints" +msgstr "Fusionner les waypoints identiques" + +#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption +#: filter.dfm:557 +msgid "Duplicates" +msgstr "Doublons" + +#. frmFilter..gbWaypoints..cbWayptRadius..Hint +#: filter.dfm:566 +msgid "Include points based on their proximity to central point" +msgstr "Inclure les points en fonction de la proximité d'un point central" + +#. frmFilter..gbWaypoints..cbWayptRadius..Caption +#: filter.dfm:567 +msgid "Radius" +msgstr "Rayon" + +#. frmFilter..gbWaypoints..edWayptRadiusLat..Hint +#: filter.dfm:595 +msgid "Latitude of central point" +msgstr "Latitude du point central" + +#. frmFilter..gbWaypoints..edWayptRadiusLon..Hint +#: filter.dfm:605 +msgid "Longitude of central point" +msgstr "Longitude du point central" + +#. frmFilter..gbTransform..Caption +#: filter.dfm:617 +msgid "Transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransform..Caption +#: filter.dfm:634 +msgid "Transform" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Hint +#: filter.dfm:643 +msgid "Delete source data after transformation" +msgstr "" + +#. frmFilter..gbTransform..cbTransformDelete..Caption +#: filter.dfm:644 +msgid "Delete" +msgstr "" + +#. frmMain..pnTop..gbInput..Caption +#: main.dfm:38 +#: main.pas:270 +#: main.pas:275 +#: main.pas:471 +#: main.pas:872 +msgid "Input" +msgstr "Entrée" + +#. frmMain..pnTop..gbInput..sbOpenFile..Hint +#: main.dfm:45 +msgid "Start the file open dialog" +msgstr "Menu de d'ouverture de fichier" + +#. frmMain..pnTop..gbInput..lbInputOpts..Caption +#. frmMain..pnTop..gbOutput..lbOutputOpts..Caption +#. frmMain..ActionList1..acOptionsSourceFormat..Category +#. frmMain..ActionList1..acOptionsTargetFormat..Category +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Category +#: main.dfm:68 +#: main.dfm:229 +#: main.dfm:1418 +#: main.dfm:1423 +#: main.dfm:1437 +msgid "Options" +msgstr "Options" + +#. frmMain..pnTop..gbInput..lbInputFormat..Caption +#. frmMain..pnTop..gbOutput..lbOutputFormat..Caption +#: main.dfm:76 +#: main.dfm:259 +msgid "Format" +msgstr "Format" + +#. frmMain..pnTop..gbInput..lbInputFile..Caption +#. frmMain..pnTop..gbOutput..lbOutputFile..Caption +#. frmMain..ActionList1..acFileExit..Category +#. frmMain..ActionList1..acFileClearMemo..Category +#. frmMain..ActionList1..acFileOutputToScreen..Category +#. frmMain..ActionList1..acFileChangeLanguage..Category +#. frmMain..ActionList1..acFileExportCSV..Category +#: main.dfm:83 +#: main.dfm:266 +#: main.dfm:1399 +#: main.dfm:1428 +#: main.dfm:1443 +#: main.dfm:1455 +#: main.dfm:1460 +#: main.pas:869 +#: main.pas:923 +msgid "File" +msgstr "Fichier" + +#. frmMain..pnTop..gbInput..chbInputDevice..Hint +#: main.dfm:112 +msgid "Read data from device instead from file" +msgstr "Lire les données depuis un périphérique plutôt qu'un fichier" + +#. frmMain..pnTop..gbInput..chbInputDevice..Caption +#. frmMain..pnTop..gbOutput..chbOutputDevice..Caption +#: main.dfm:115 +#: main.dfm:299 +msgid "Device" +msgstr "Périphérique" + +#. frmMain..pnTop..gbInput..edInputOpts..Hint +#: main.dfm:124 +msgid "Options for the selected input format" +msgstr "Options du format d'entrée sélectionné" + +#. frmMain..pnTop..gbInput..edInputFile..Hint +#: main.dfm:135 +msgid "Read data from given filename" +msgstr "Lire les données de puis un fichier" + +#. frmMain..pnTop..gbInput..cbInputLang..Hint +#: main.dfm:146 +msgid "Characterset for input data" +msgstr "Code de caractères pour l'entrée" + +#. frmMain..pnTop..gbInput..cbInputLang....Items.Strings +#. frmMain..pnTop..gbOutput..cbOutputLang....Items.Strings +#: main.dfm:152 +#: main.dfm:363 +msgid "- default -" +msgstr "- défaut -" + +#. frmMain..pnTop..gbInput..cbInputDevice..Hint +#: main.dfm:179 +msgid "Read data from device ..." +msgstr "Lire les données depuis le périphérique" + +#. frmMain..pnTop..gbInput..cbInputFormatDevice..Hint +#: main.dfm:194 +msgid "Format for input from device" +msgstr "Format d'entrée depuis le périphérique" + +#. frmMain..pnTop..gbInput..cbInputFormat..Hint +#: main.dfm:208 +msgid "Format for input from file" +msgstr "Format d'entrée depuis un fichier" + +#. frmMain..pnTop..gbOutput..Caption +#: main.dfm:222 +#: main.pas:271 +#: main.pas:276 +#: main.pas:480 +#: main.pas:926 +msgid "Output" +msgstr "Sortie" + +#. frmMain..pnTop..gbOutput..sbSaveFile..Hint +#: main.dfm:273 +msgid "Start the file save dialog" +msgstr "Menu de sauvegarde de fichier" + +#. frmMain..pnTop..gbOutput..chbOutputDevice..Hint +#: main.dfm:296 +msgid "Write data to device instead to file" +msgstr "Ecrire les données sur le périphérique plutôt que dans un fichier" + +#. frmMain..pnTop..gbOutput..cbOutputFormatDevice..Hint +#: main.dfm:309 +msgid "Format for ouput to device" +msgstr "Format de sortie vers le périphérique" + +#. frmMain..pnTop..gbOutput..edOutputOpts..Hint +#: main.dfm:321 +msgid "Options for the selected output format" +msgstr "Options du format de sortie sélectionné" + +#. frmMain..pnTop..gbOutput..cbOutputFormat..Hint +#: main.dfm:332 +msgid "Format for output to file" +msgstr "Format de sortie vers un fichier" + +#. frmMain..pnTop..gbOutput..edOutputFile..Hint +#: main.dfm:345 +msgid "Write data to given filename" +msgstr "Ecrire les données dans un fichier" + +#. frmMain..pnTop..gbOutput..cbOutputLang..Hint +#: main.dfm:357 +msgid "Characterset for output data" +msgstr "Code de caractères pour la sortie" + +#. frmMain..pnTop..gbOutput..cbOutputDevice..Hint +#: main.dfm:390 +msgid "Write data to device ..." +msgstr "Ecrire les données sur le périphérique" + +#. frmMain..pnBottom..lbWhat..Caption +#: main.dfm:415 +msgid "What ?" +msgstr "Quoi ?" + +#. frmMain..pnBottom..cbWaypoints..Hint +#: main.dfm:554 +msgid "Process waypoint information" +msgstr "Inclure les waypoints" + +#. frmMain..pnBottom..cbRoutes..Hint +#: main.dfm:568 +msgid "Process route information" +msgstr "Inclure les routes" + +#. frmMain..pnBottom..cbRoutes..Caption +#: main.dfm:569 +msgid "&Routes" +msgstr "&Routes" + +#. frmMain..pnBottom..cbTracks..Hint +#: main.dfm:580 +msgid "Process track information" +msgstr "Inclure les traces" + +#. frmMain..pnBottom..btnFilter..Caption +#. frmMain..ActionList1..acFilterSelect..Caption +#: main.dfm:594 +#: main.dfm:1393 +msgid "&Filter" +msgstr "&Filtre" + +#. frmMain..pnBottom..btnProcess..Hint +#: main.dfm:638 +msgid "Start data conversion" +msgstr "Démarrer la conversion de données" + +#. frmMain..pnBottom..btnProcess..Caption +#. frmMain..ActionList1..acConvert..Caption +#: main.dfm:641 +#: main.dfm:1386 +msgid "let's go" +msgstr "Lancer" + +#. frmMain..OpenDialog..Filter +#: main.dfm:701 +msgid "Garmin Mapsource mps|*.mps|All files|*.*" +msgstr "Garmin Mapsource mps|*.mps|Tous les fichiers|*.*" + +#. frmMain..SaveDialog..Filter +#: main.dfm:707 +msgid "All file(s)|*.*|Garmin MapSource mps|*.mps" +msgstr "Tous les fichier(s)|*.*|Garmin MapSource mps|*.mps" + +#. frmMain..ActionList1..acConvert..Category +#. frmMain..ActionList1..acFilterSelect..Category +#: main.dfm:1385 +#: main.dfm:1392 +msgid "Babel" +msgstr "Babel" + +#. frmMain..ActionList1..acFilterSelect..Hint +#: main.dfm:1394 +msgid "Filter incomming data before writing them to file or device" +msgstr "Filtrer les données envoyées avant de les écrire sur un périphérique ou dans un fichier" + +#. frmMain..ActionList1..acFileExit..Caption +#: main.dfm:1400 +msgid "E&xit" +msgstr "F&ermer" + +#. frmMain..ActionList1..acHelpAbout..Category +#. frmMain..ActionList1..acHelpIntro..Category +#. frmMain..ActionList1..acHelpReadme..Category +#: main.dfm:1404 +#: main.dfm:1409 +#: main.dfm:1413 +msgid "Help" +msgstr "Aide" + +#. frmMain..ActionList1..acHelpAbout..Caption +#: main.dfm:1405 +msgid "&About" +msgstr "&A propos" + +#. frmMain..ActionList1..acHelpIntro..Caption +#: main.dfm:1410 +msgid "&Intro" +msgstr "&Introduction" + +#. frmMain..ActionList1..acHelpReadme..Caption +#. frmReadme..Caption +#: main.dfm:1414 +#: readme.dfm:6 +msgid "GPSBabel README" +msgstr "GPSBabel README" + +#. frmMain..ActionList1..acOptionsSourceFormat..Caption +#: main.dfm:1419 +msgid "... for source format" +msgstr "... pour le format source" + +#. frmMain..ActionList1..acOptionsTargetFormat..Caption +#: main.dfm:1424 +msgid "... for target format" +msgstr "... pour le format cible" + +#. frmMain..ActionList1..acFileClearMemo..Caption +#: main.dfm:1429 +msgid "Clear output" +msgstr "Effacer la sortie" + +#. frmMain..ActionList1..acFileClearMemo..Hint +#: main.dfm:1430 +msgid "Clear messages" +msgstr "Effacer les messages" + +#. frmMain..ActionList1..acOptionsEnableCharactersetTransformation..Caption +#: main.dfm:1438 +msgid "Enable characterset transformation" +msgstr "Activer la transformation du code de caractères" + +#. frmMain..ActionList1..acFileOutputToScreen..Caption +#: main.dfm:1444 +msgid "Output to screen" +msgstr "Afficher sur l'écran" + +#. frmMain..ActionList1..acFileChangeLanguage..Caption +#: main.dfm:1456 +msgid "Change language" +msgstr "Changer de langue" + +#. frmMain..ActionList1..acFileExportCSV..Caption +#: main.dfm:1461 +msgid "Export gpsbabel.csv (unicode)" +msgstr "Export gpsbabel.csv (unicode)" + +#. frmMain..MainMenu1..mnuFile..Caption +#: main.dfm:1469 +msgid "&File" +msgstr "&Fichier" + +#. frmMain..MainMenu1..mnuFile..File1..Caption +#: main.dfm:1477 +msgid "Export" +msgstr "Export" + +#. frmMain..MainMenu1..mnuOptions..Caption +#: main.dfm:1498 +msgid "&Options" +msgstr "&Options" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames..Caption +#: main.dfm:1500 +msgid "Synthesize shortnames" +msgstr "Générer les nom courts" + +#. frmMain..MainMenu1..mnuOptions..mnuSynthesizeShortNames....Hint +#: main.dfm:1503 +msgid "Ignore shortnames from source data and synthesize them from description or notes" +msgstr "Ingorer les noms \"courts\" de la source de données et les générer à partir des noms longs" + +#. frmMain..MainMenu1..mnuOptions..mnuOptionsForceDataType..Caption +#: main.dfm:1507 +msgid "Force selected GPS data types (nuketypes filter)" +msgstr "Forcer le type de données GPS selctionné (filtre nuketypes)" + +#. frmMain..MainMenu1..mnuHelp..Caption +#: main.dfm:1548 +msgid "&Help" +msgstr "&Aide" + +#. frmOptions..Caption +#: options.dfm:5 +msgid "Options for ..." +msgstr "Options pour ..." + +#. frmSelect..pnBottom..btnCancel..Caption +#: select.dfm:66 +msgid "Abort" +msgstr "Annuler" + +#: about.pas:87 +#: select.pas:81 +msgid "German" +msgstr "Allemand" + +#: about.pas:88 +#: select.pas:83 +msgid "French" +msgstr "Français" + +#: about.pas:89 +#: select.pas:82 +msgid "Spanish" +msgstr "Espagnol" + +#: about.pas:131 +msgid "" +"Please have a look at the file README.GUI.\n" +"\n" +"There you will find all information you need to\n" +"get GPSBabelGUI working in your own language." +msgstr "" +"Consultez le fichier README.GUI\n" +"\n" +"Vous trouverez toutes l'information nécessaire\n" +"pour faire fonctionner GPSBabelGUI dans votre langue." + +#: filter.pas:178 +#: filter.pas:179 +#: filter.pas:182 +#: filter.pas:183 +msgid "Waypoints" +msgstr "Waypoints" + +#: filter.pas:178 +#: filter.pas:179 +#: filter.pas:180 +#: filter.pas:181 +msgid "Routes" +msgstr "Routes" + +#: filter.pas:180 +#: filter.pas:181 +#: filter.pas:182 +#: filter.pas:183 +msgid "Tracks" +msgstr "Traces" + +#: filter.pas:222 +msgid "Feet" +msgstr "Pieds" + +#: filter.pas:223 +msgid "Meter" +msgstr "Mètre" + +#: filter.pas:226 +msgid "Miles" +msgstr "Miles" + +#: filter.pas:227 +msgid "Kilometer" +msgstr "Kilomètre" + +#: filter.pas:237 +msgid "Not supported by gpsbabel.exe, release %s!" +msgstr "Non supporté par GPSBabel, version %s!" + +#: filter.pas:285 +msgid "Value (%s) out of range (%g to %g)!" +msgstr "Valeurs (%s) en dehors des limites (%g à %g)!" + +#: filter.pas:590 +#: options.pas:661 +msgid "Discard changes?" +msgstr "Ne pas tenir compte des changements?" + +#: main.pas:244 +msgid "Internal development release" +msgstr "Version interne" + +#: main.pas:246 +msgid "BETA" +msgstr "BETA" + +#: main.pas:248 +msgid "Private release" +msgstr "Version privée" + +#: main.pas:250 +msgid "Special release" +msgstr "Version spéciale" + +#: main.pas:346 +msgid "The file \"gpsbabel.exe\" found in current directory is too old!" +msgstr "Le fichier \"gpsbabel.exe\" présent dans le répertoir courant est trop vieux!" + +#: main.pas:420 +#: main.pas:554 +msgid "All files|*.*" +msgstr "Tous les fichiers|*.*" + +#: main.pas:488 +msgid "Select and edit options for \"%s\"" +msgstr "Selctionner et éditer les options pour \"%s\"" + +#: main.pas:492 +msgid "No options available for \"%s\"" +msgstr "Pas d'option disponible pour \"%s\"" + +#. s := s + '-1'; +#: main.pas:607 +msgid "File %s not found." +msgstr "Fichier%s non trouvé." + +#: main.pas:668 +msgid "File \"%s\" exists ! Overwrite ?" +msgstr "Le fichier \"%s\" existe déjà ! Ecraser ?" + +#: main.pas:669 +msgid "Warning" +msgstr "Attention" + +#: main.pas:702 +msgid "Could not run \"gpsbabel.exe\"!" +msgstr "Impossible d'éxécuter \"gpsbabel.exe\"!" + +#: main.pas:711 +msgid "Sorry, gpsbabel.exe reported problems!" +msgstr "Désolé, GPSBabel a reporté un problème !" + +#: main.pas:713 +msgid "Converted successfully from \"%s\" to \"%s\"." +msgstr "Conversion de \"%s\" à \"%s\" réussie." + +#: main.pas:824 +msgid "GPSBabel, version %s" +msgstr "GPSBabel, version %s" + +#: main.pas:858 +#: main.pas:913 +msgid "Port" +msgstr "Port" + +#: main.pas:1017 +msgid "Options for \"%s\"" +msgstr "Options pour \"%s\"" + +#: main.pas:1207 +#: main.pas:1277 +msgid "Choose language" +msgstr "Choisir la langue" + +#: main.pas:1207 +msgid "for GUIBabelGUI" +msgstr "pour GPSBabelGUI" + +#: main.pas:1277 +msgid "for export" +msgstr "pour export" + +#. override; +#: options.pas:147 +msgid "Be aware, that most options are made for the output side. " +msgstr "Attention, la plupart des options sont faites pour le format de sortie." + +#: options.pas:148 +msgid "Currently we don't have a flag which tells us which direction is used by the options." +msgstr "Nous n'avons pour l'instant pas de drapeau indiquant dans quelle direction sont utilisées les options." + +#: options.pas:208 +msgid "Short \"%s\"" +msgstr "Raccourci \"%s\"" + +#: options.pas:332 +msgid "Invalid line format!" +msgstr "Format de ligne invalide" + +#: options.pas:353 +msgid "Unknown option \"%s\"!" +msgstr "Option inconnue \"%s\"" + +#: select.pas:84 +msgid "English" +msgstr "Anglais" + +#: utils.pas:119 +msgid "Error WINAPI: Could not create \"NamedPipe\"!" +msgstr "Erreur WIANPI: Ne peut pas créer \"NamedPipe\"!" + +#: utils.pas:124 +msgid "\"gpsbabel.exe\" not found!!!" +msgstr "\"gpsbabel.exe\" non trouvé!!!" + +#. dwCreationFlags, // creation flags +#: utils.pas:143 +msgid "Could not run \"gpsbabel.exe\" (Error %d)!" +msgstr "Impossible d'éxecuter \"gpsbabel.exe\" (Error %d)!" + +#: utils.pas:176 +msgid "\"gpsbabel.exe\" returned error 0x%x (%d)" +msgstr "\"gpsbabel.exe\" a renvoyé l'erreur 0x%x (%d)" + diff --git a/win32/gui-2/locale/fr/LC_MESSAGES/delphi.po b/win32/gui-2/locale/fr/LC_MESSAGES/delphi.po new file mode 100644 index 000000000..0f96748ed --- /dev/null +++ b/win32/gui-2/locale/fr/LC_MESSAGES/delphi.po @@ -0,0 +1,6177 @@ +msgid "" +msgstr "" +"Project-Id-Version: Borland Delphi 5 Runtime libraries\n" +"POT-Creation-Date: 2003-03-04 15:18\n" +"PO-Revision-Date: 2006-04-14 14:12+0100\n" +"Last-Translator: Olaf Klein \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: dxgettext 1.2\n" +"License: May only be used with a purchased Borland Delphi\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" + +#. Programmer's name for it: sRowError +#: Decision Cube/mxconsts.pas:27 +msgid "row error" +msgstr "Erreur ligne" + +#. Programmer's name for it: sAllValues +#: Decision Cube/mxconsts.pas:29 +msgid "All Values" +msgstr "Toutes les valeurs" + +#. Programmer's name for it: sMovetoRow +#: Decision Cube/mxconsts.pas:30 +msgid "Move to Row Area" +msgstr "Déplacer vers zone Ligne" + +#. Programmer's name for it: sMovetoCol +#: Decision Cube/mxconsts.pas:31 +msgid "Move to Column Area" +msgstr "Déplacer vers zone Colonne" + +#. Programmer's name for it: sMakeDimOpen +#: Decision Cube/mxconsts.pas:32 +msgid "Open Dimension" +msgstr "Ouvrir dimension" + +#. Programmer's name for it: sDrilled +#: Decision Cube/mxconsts.pas:33 +msgid "Drilled In" +msgstr "Perforé" + +#. Programmer's name for it: sCouldNotOpen +#: Decision Cube/mxconsts.pas:34 +msgid "The information requested could not be loaded. " +msgstr "L'information demandée n'a pas pu être chargée. " + +#. Programmer's name for it: sNoSumsAvailable +#: Decision Cube/mxconsts.pas:35 +msgid "No active summaries have been defined. " +msgstr "Aucun récapitulatif actif n'a été défini. " + +#. Programmer's name for it: sNoSumsCouldBeLoaded +#: Decision Cube/mxconsts.pas:36 +msgid "Not enough room available to load a summary. " +msgstr "Pas assez de place disponible pour charger un récapitulatif. " + +#. Programmer's name for it: sNoDimsAvailable +#: Decision Cube/mxconsts.pas:37 +msgid "No available dimensions have been defined. " +msgstr "Aucune dimension disponible n'a été définie. " + +#. Programmer's name for it: sNoDimsCouldBeLoaded +#: Decision Cube/mxconsts.pas:38 +msgid "Not enough space available to load a dimension. " +msgstr "Pas assez d'espace pour charger une dimension. " + +#. Programmer's name for it: sTemplatePrefix +#: Decision Cube/mxconsts.pas:40 +msgid "Template: " +msgstr "Modèle : " + +#. Programmer's name for it: sGridCellError +#: Decision Cube/mxconsts.pas:42 +msgid "[Error]" +msgstr "[Erreur]" + +#. Programmer's name for it: sTotalCaption +#: Decision Cube/mxconsts.pas:43 +msgid "Sum" +msgstr "Somme" + +#. Programmer's name for it: sActivateLabel +#: Decision Cube/mxconsts.pas:44 +msgid "Inactive Dimensions" +msgstr "Dimensions inactives" + +#. Programmer's name for it: sRowCaption +#: Decision Cube/mxconsts.pas:45 +msgid "R" +msgstr "L" + +#. Programmer's name for it: sColCaption +#: Decision Cube/mxconsts.pas:46 +msgid "C" +msgstr "C" + +#. Programmer's name for it: sCaptionMenu1 +#: Decision Cube/mxconsts.pas:47 +msgid "Display Data and Subtotals" +msgstr "Afficher les données et les sous-totaux" + +#. Programmer's name for it: sCaptionMenu2 +#: Decision Cube/mxconsts.pas:48 +msgid "Display Data Only" +msgstr "Afficher seulement les données" + +#. Programmer's name for it: sCaptionMenu3 +#: Decision Cube/mxconsts.pas:49 +msgid "Display Subtotals Only" +msgstr "Afficher seulement les sous-totaux" + +#. Programmer's name for it: sDrillIn +#: Decision Cube/mxconsts.pas:50 +msgid "Drill in to this value" +msgstr "Percer jusqu'à cette valeur" + +#. Programmer's name for it: sGridMenu1 +#: Decision Cube/mxconsts.pas:51 +msgid "Subtotals on/off" +msgstr "Sous-totaux oui/non" + +#. Programmer's name for it: sGridMenu2 +#: Decision Cube/mxconsts.pas:52 +msgid "Decision Cube Editor.." +msgstr "Editeur de cube de décision..." + +#. Programmer's name for it: sGridMenu3 +#: Decision Cube/mxconsts.pas:53 +msgid "Decision Query Editor.." +msgstr "Editeur de requête de décision..." + +#. Programmer's name for it: sGridMenu4 +#: Decision Cube/mxconsts.pas:54 +msgid "Show Detail Records.." +msgstr "Montrer les enregistrements détail." + +#. Programmer's name for it: sUnsupportedDataType +#: Decision Cube/mxconsts.pas:57 +msgid "Unsupported data type : %s" +msgstr "Type de données non supporté : %s" + +#. Programmer's name for it: sRowOutOfRange +#: Decision Cube/mxconsts.pas:58 +msgid "Row index out of range : %d" +msgstr "Index de ligne hors limites : %d" + +#. Programmer's name for it: sColOutOfRange +#: Decision Cube/mxconsts.pas:59 +msgid "Column index out of range : %d" +msgstr "Index de colonne hors limites : %d" + +#. Programmer's name for it: sDupeItem +#: Decision Cube/mxconsts.pas:60 +msgid "Duplicate item in array" +msgstr "Elément dupliqué dans le tableau" + +#. Programmer's name for it: sArrayIndexOutOfRange +#: Decision Cube/mxconsts.pas:61 +msgid "Array index out of range : %d" +msgstr "Index de tableau hors limites : %d" + +#. Programmer's name for it: sLowCapacityError +#: Decision Cube/mxconsts.pas:62 +msgid "The DecisionCube Capacity is low. Please deactivate dimensions or change the data set." +msgstr "La capacité du cube de décision est faible. Désactivez des dimensions ou modifiez le dataset." + +#. Programmer's name for it: sQryNotInitialized +#: Decision Cube/mxconsts.pas:63 +msgid "Query could not be run. Check that the query, SQL text, and Database are correct." +msgstr "La requête n'a pu être exécutée. Vérifiez que la requête, le texte SQL et la base de données sont corrects." + +#. Programmer's name for it: sSortedListError +#: Decision Cube/mxconsts.pas:64 +msgid "Operation not allowed on sorted string list." +msgstr "Opération non autorisée sur une liste de chaînes triée." + +#. Programmer's name for it: sDuplicateString +#: Decision Cube/mxconsts.pas:65 +msgid "String list does not allow duplicates." +msgstr "La liste de chaînes n'autorise pas les doublons." + +#. Programmer's name for it: sMaxAllowedSums +#: Decision Cube/mxconsts.pas:66 +msgid "The maximum allowed summaries of %d has been exceeded." +msgstr "Le nombre maximum de %d récapitulatifs a été dépassé." + +#. Programmer's name for it: sGeneralArrayError +#: Decision Cube/mxconsts.pas:67 +msgid "General array error." +msgstr "Erreur générale de tableau." + +#. Programmer's name for it: sDimIndexError +#: Decision Cube/mxconsts.pas:70 +msgid "Illegal Dimension Index" +msgstr "Index de dimension illégal" + +#. Programmer's name for it: sIllegalValueForBin +#: Decision Cube/mxconsts.pas:73 +msgid "Initial Value is not legal for this type of Grouping" +msgstr "Valeur initiale illégale pour ce type de groupage" + +#. Programmer's name for it: sIllegalDimMap +#: Decision Cube/mxconsts.pas:74 +msgid "Dimension Map is not the correct size" +msgstr "Carte de dimension de taille incorrecte" + +#. Programmer's name for it: sDimMapActiveError +#: Decision Cube/mxconsts.pas:75 +msgid "Cannot perform this action on an active Dimension Map" +msgstr "Impossible d'effectuer cette action sur une carte de dimensions active" + +#. Programmer's name for it: sNotAvailable +#: Decision Cube/mxconsts.pas:76 +msgid "Not Available" +msgstr "Non disponible" + +#. Programmer's name for it: sGetValueCounts +#: Decision Cube/mxconsts.pas:77 +msgid "Information required to do Maximum Cell limit is not current. Do you want to fetch it now?" +msgstr "L'information requise pour calculer la limite de cellule maximum n'est pas à jour. Voulez-vous l'obtenir maintenant ?" + +#. Programmer's name for it: sDateBinningNotAllowed +#: Decision Cube/mxconsts.pas:78 +msgid "Date grouping is not allowed for fields of this type" +msgstr "Le groupage par date n'est pas autorisé pour ces types de champs" + +#. Programmer's name for it: sEmptyDataSet +#: Decision Cube/mxconsts.pas:79 +msgid "Cannot build the Decision Cube with an empty data set" +msgstr "Impossible de construire le cube de décision avec un ensemble de données vide" + +#. Programmer's name for it: sNoDataSet +#: Decision Cube/mxconsts.pas:82 +msgid "Data set property is not assigned" +msgstr "La propriété dataset n'est pas affectée" + +#. Programmer's name for it: sNoAggs +#: Decision Cube/mxconsts.pas:83 +msgid "No summaries are defined. " +msgstr "Aucun récapitulatif n'est défini. " + +#. Programmer's name for it: sNoDims +#: Decision Cube/mxconsts.pas:84 +msgid "No dimension fields are defined. " +msgstr "Pas de champs de dimensions définis. " + +#. Programmer's name for it: sUnknownDims +#: Decision Cube/mxconsts.pas:85 +msgid "The dimension types for this dataset cannot be determined automatically. You must map the fields to dimensions or summaries with the Decision Cube Editor" +msgstr "Les types de dimensions pour cet ensemble de données ne peuvent être déterminés automatiquement. Vous devez affecter les champs aux dimensions ou récapitulatifs avec l'éditeur de cube de décision." + +#. Programmer's name for it: sGroupsMissing +#: Decision Cube/mxconsts.pas:86 +msgid "All dimension fields must be grouped. " +msgstr "Tous les champs de dimensions doivent être groupés. " + +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#. Programmer's name for it: sDecisionQueryError +#. Programmer's name for it: sQueryError +#: Decision Cube/mxconsts.pas:87 +#: Vcl/mxconsts.pas:89 +msgid "The query may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "La requête est mal définie, ou vous devez affecter ses champs aux dimensions ou récapitulatifs actifs avec l'éditeur de cube de décision." + +#. Programmer's name for it: sDataSetError +#: Decision Cube/mxconsts.pas:88 +msgid "The dataset may be incorrectly defined, or you may need to map its fields to active dimensions or summaries with the Decision Cube Editor" +msgstr "Le dataset est incorrectement défini, ou vous devez affecter ses champs aux dimensions ou récapitulatifs actifs avec l'éditeur de cube de décision." + +#. Programmer's name for it: sCountStar +#: Decision Cube/mxconsts.pas:90 +msgid "COUNTALL" +msgstr "COUNTALL" + +#. Programmer's name for it: sAddAvgWarning +#: Decision Cube/mxconsts.pas:91 +msgid "Average is calculated using sum and count summaries for each field. The necessary summaries have been added." +msgstr "La moyenne est calculée en utilisant les récapitulatifs somme et nombre pour chaque champ. Les récapitulatifs nécessaires ont été ajoutés." + +#. Programmer's name for it: sAddAvgStarWarning +#: Decision Cube/mxconsts.pas:92 +msgid "Average is calculated using a field sum and count(*). The necessary summaries have been added." +msgstr "La moyenne est calculée en utilisant la somme et le nombre du champ(*). Les récapitulatifs nécessaires ont été ajoutés." + +#. Programmer's name for it: sQueryLegal +#: Decision Cube/mxconsts.pas:95 +msgid "Query is legal." +msgstr "La requête est légale." + +#. Programmer's name for it: sAddFieldExists +#: Decision Cube/mxconsts.pas:96 +msgid " is already in the query" +msgstr " est déjà dans la requête" + +#. Programmer's name for it: sAggTypeNotAllowed +#: Decision Cube/mxconsts.pas:97 +msgid " is not an allowed summary type" +msgstr " n'est pas un type de récapitulatif autorisé" + +#. Programmer's name for it: sDimTypeNotAllowed +#: Decision Cube/mxconsts.pas:98 +msgid " is not an allowed dimension type" +msgstr " n'est pas un type de dimension autorisé" + +#. Programmer's name for it: sAverageRequires +#: Decision Cube/mxconsts.pas:99 +msgid "Average summaries use Sum and Count" +msgstr "Les récapitulatifs Moyenne utilisent Sum et Count" + +#. Programmer's name for it: sWantToExit +#: Decision Cube/mxconsts.pas:100 +msgid "Do you still want to Exit?" +msgstr "Voulez-vous quand-même quitter ?" + +#. Programmer's name for it: sQueryIllegal +#: Decision Cube/mxconsts.pas:101 +msgid "The query you have created is not legal." +msgstr "La requête que vous avez créée n'est pas correcte." + +#. Programmer's name for it: sQueryEditIllegal +#: Decision Cube/mxconsts.pas:102 +msgid "The query you have entered is not legal. Please correct it before continuing." +msgstr "La requête que vous avez saisie n'est pas correcte. Veuillez la corriger avant de continuer." + +#. Programmer's name for it: sRemoveFieldError +#: Decision Cube/mxconsts.pas:103 +msgid "Could not remove the field" +msgstr "Impossible d'enlever le champ" + +#. Programmer's name for it: sAllFields +#: Decision Cube/mxconsts.pas:104 +msgid "All Fields" +msgstr "Tous les champs" + +#. Programmer's name for it: sQueryFields +#: Decision Cube/mxconsts.pas:105 +msgid "Query Fields" +msgstr "Champs de requête" + +#. Programmer's name for it: sEditDone +#: Decision Cube/mxconsts.pas:106 +msgid "&Edit Done" +msgstr "Modi&fications terminées" + +#. Programmer's name for it: sEditQuery +#. DSSQueryEditor..Pager..Query..EditQry..Caption +#: Decision Cube/mxconsts.pas:107 +msgid "&Edit Query" +msgstr "&Modifier la requête" + +#. Programmer's name for it: sQParseRemovedField +#: Decision Cube/mxconsts.pas:110 +msgid "One or more fields of a type which cannot be tabulated were removed from the query." +msgstr "Un champ ou plusieurs d'un type ne pouvant être tabulé ont été supprimés de la requête." + +#. Programmer's name for it: sCubeLimitsExceeded +#: Decision Cube/mxconsts.pas:113 +msgid "Decision Cube size excedes limits" +msgstr "La taille du cube de décision dépasse les limites" + +#. Programmer's name for it: sMaxAllowedDims +#: Decision Cube/mxconsts.pas:114 +msgid "The maximum allowed dimensions of %d has been exceeded." +msgstr "Le nombre maximum de %d dimensions a été dépassé." + +#. Programmer's name for it: sMaxAllowedCells +#: Decision Cube/mxconsts.pas:115 +msgid "Total cell count of %d exceeds the maximum of %d." +msgstr "Le nombre total de cellules, %d, dépasse le maximum de %d." + +#. Programmer's name for it: sUnsupportedFieldType +#: Decision Cube/mxconsts.pas:116 +msgid "Field %s has an unsupported data type: %s" +msgstr "Le champ %s a un type de données non supporté : %s" + +#. Programmer's name for it: sFetchValues +#: Decision Cube/mxconsts.pas:117 +msgid "Scanning data set values..." +msgstr "Parcours des valeurs de l'ensemble de données..." + +#. Programmer's name for it: sUserCanceled +#: Decision Cube/mxconsts.pas:118 +msgid "User canceled DecisionCube population." +msgstr "L'utilisateur a annulé la population du cube de décision." + +#. Programmer's name for it: sBinningValues +#: Decision Cube/mxconsts.pas:119 +msgid "Grouping values ..." +msgstr "Valeurs de groupage ..." + +#. Programmer's name for it: sCreatingIndexes +#: Decision Cube/mxconsts.pas:120 +msgid "Creating Cube index for %s ..." +msgstr "Création de l'indice de cube pour %s ..." + +#. Programmer's name for it: sCreateDerivedSummaryError +#: Decision Cube/mxconsts.pas:121 +msgid "Unable to create derived summary." +msgstr "Impossible de créer le récapitulatif dérivé." + +#. Programmer's name for it: sTrue +#. Programmer's name for it: STextTrue +#. Programmer's name for it: sTrue +#: Decision Cube/mxconsts.pas:122 +msgid "True" +msgstr "Vrai" + +#. Programmer's name for it: sFalse +#. Programmer's name for it: STextFalse +#. Programmer's name for it: sFalse +#: Decision Cube/mxconsts.pas:123 +msgid "False" +msgstr "Faux" + +#. Programmer's name for it: sBinTypeMismatch +#: Decision Cube/mxconsts.pas:124 +msgid "The bin type does not match the fieldtype." +msgstr "Le type de casier ne correspond pas au type de champ." + +#. Programmer's name for it: sFatalCacheError +#: Decision Cube/mxconsts.pas:125 +msgid "Fatal error in cache: code: %d" +msgstr "Erreur fatale dans le cache, code : %d" + +#. Programmer's name for it: sStringTypeNoSupported +#: Decision Cube/mxconsts.pas:126 +msgid "String Data type not supported for summaries" +msgstr "Type chaîne non supporté pour les récapitulatifs" + +#. Programmer's name for it: sDataSetTooLarge +#: Decision Cube/mxconsts.pas:127 +msgid "Dataset is too large" +msgstr "L'ensemble de données est trop grand" + +#. Programmer's name for it: sBuildingDataStore +#: Decision Cube/mxconsts.pas:128 +msgid "Building data store..." +msgstr "Construction du magasin de données..." + +#. Programmer's name for it: sSumLabel +#: Decision Cube/mxconsts.pas:131 +msgid "Sum of %s" +msgstr "Somme de %s" + +#. Programmer's name for it: sCountLabel +#: Decision Cube/mxconsts.pas:132 +msgid "Count of %s" +msgstr "Nombre de %s" + +#. Programmer's name for it: sMaxLabel +#: Decision Cube/mxconsts.pas:133 +msgid "Maximum of %s" +msgstr "Maximum de %s" + +#. Programmer's name for it: sMinLabel +#: Decision Cube/mxconsts.pas:134 +msgid "Minimum of %s" +msgstr "Minimum de %s" + +#. Programmer's name for it: sAverageLabel +#: Decision Cube/mxconsts.pas:135 +msgid "Average of %s" +msgstr "Moyenne de %s" + +#. Programmer's name for it: sVarLabel +#: Decision Cube/mxconsts.pas:136 +msgid "Variance of %s" +msgstr "Variance de %s" + +#. Programmer's name for it: sSDLabel +#: Decision Cube/mxconsts.pas:137 +msgid "Standard Deviation of %s" +msgstr "Ecart-type de %s" + +#. Programmer's name for it: sAggLabel +#: Decision Cube/mxconsts.pas:138 +msgid "Summary of %s" +msgstr "Récapitulatif de %s" + +#. Programmer's name for it: sUnsupportedVarType +#: Decision Cube/mxconsts.pas:139 +msgid "Unsupported Data Type %d" +msgstr "Type de données non supporté : %d" + +#. Programmer's name for it: sOtherValues +#: Decision Cube/mxconsts.pas:140 +msgid "Other Values" +msgstr "Autres valeurs" + +#. Programmer's name for it: sSelectFromError +#: Decision Cube/mxconsts.pas:142 +msgid "Query lacks a Select/From clause." +msgstr "Il manque une clause Select/From à la requête" + +#. Programmer's name for it: sArgumentExpected +#: Decision Cube/mxconsts.pas:143 +msgid "No argument provided for an operator or summary" +msgstr "Aucun argument fourni pour un opérateur ou un récapitulatif" + +#. Programmer's name for it: sGroupOnExpressionError +#: Decision Cube/mxconsts.pas:144 +msgid "An expression cannot be used for a grouping field" +msgstr "Une expression ne peut être utilisée dans un champ groupé" + +#. Programmer's name for it: SOutofBounds +#: Decision Cube/mxconsts.pas:146 +msgid "Out of Bounds" +msgstr "Hors limites" + +#. Programmer's name for it: sIDAPILangID +#. Programmer's name for it: SIDAPILangID +#. Programmer's name for it: sIDAPILangID +#: Decision Cube/mxconsts.pas:147 +msgid "0009" +msgstr "000C" + +#. Programmer's name for it: sComponentTabName +#: Decision Cube/mxdconst.pas:14 +msgid "Decision Cube" +msgstr "Decision Cube" + +#. Programmer's name for it: sQueryVerb0 +#: Decision Cube/mxdconst.pas:15 +msgid "&Graphical Query Builder..." +msgstr "&Constructeur de requêtes graphiques..." + +#. Programmer's name for it: sQueryVerb1 +#: Decision Cube/mxdconst.pas:16 +msgid "&Decision Query Editor..." +msgstr "Edite&ur de requête de décision..." + +#. Programmer's name for it: sCubeVerb0 +#: Decision Cube/mxdconst.pas:17 +msgid "&Decision Cube Editor..." +msgstr "Edite&ur de cube de décision..." + +#. Programmer's name for it: sCubeVerb1 +#: Decision Cube/mxdconst.pas:18 +msgid "&Query Editor..." +msgstr "Edite&ur de requête..." + +#. Programmer's name for it: sGridVerb0 +#: Decision Cube/mxdconst.pas:19 +msgid "Sub&totals on/off" +msgstr "&Sous-totaux oui/non" + +#. Programmer's name for it: sSourceVerb0 +#: Decision Cube/mxdconst.pas:20 +msgid "&Do not display Sparse Rows/Columns" +msgstr "Ne &pas afficher les lignes/colonnes éparses" + +#. Programmer's name for it: sSourceVerb1 +#: Decision Cube/mxdconst.pas:21 +msgid "&Display Sparse Rows/Columns" +msgstr "Afficher les &lignes/colonnes éparses" + +#. Programmer's name for it: sGridDimOptions +#: Decision Cube/mxdconst.pas:22 +msgid "Grid Dimension Options" +msgstr "Options de dimensions de grille" + +#. Programmer's name for it: sGridDimSettings +#: Decision Cube/mxdconst.pas:23 +msgid "Grid Dimension Settings" +msgstr "Paramètres de dimensions de grille" + +#. Programmer's name for it: sCubeProperties +#: Decision Cube/mxdconst.pas:24 +msgid "Cube Properties" +msgstr "Propriétés du cube" + +#. Programmer's name for it: sOnlyOneDataModuleAllowed +#: Internet/brkrconst.pas:14 +msgid "Only one data module per application" +msgstr "Impossible d'avoir plus d'un Data Module par application" + +#. Programmer's name for it: sNoDataModulesRegistered +#: Internet/brkrconst.pas:15 +msgid "No data modules registered" +msgstr "Aucun Data Module recensé" + +#. Programmer's name for it: sNoDispatcherComponent +#: Internet/brkrconst.pas:16 +msgid "No dispatcher component found on data module" +msgstr "Il n'y a aucun Dispatcher dans le Data Module" + +#. Programmer's name for it: sTooManyActiveConnections +#: Internet/brkrconst.pas:18 +msgid "Maximum number of concurrent connections exceeded. Please try again later" +msgstr "Nombre maximum de connexions ouvertes simultanément atteint. Veuillez réessayer ultérieurement" + +#. Programmer's name for it: sInternalServerError +#: Internet/brkrconst.pas:22 +msgid "" +"Internal Server Error 500\n" +"

              Internal Server Error 500


              \n" +"Exception: %s
              \n" +"Message: %s
              \n" +msgstr "" +"Erreur interne au serveur 500\n" +"

              Erreur interne au serveur 500


              \n" +"Exception: %s
              \n" +"Message: %s
              \n" + +#. Programmer's name for it: sDocumentMoved +#: Internet/brkrconst.pas:26 +msgid "" +"Document Moved 302\n" +"

              Object Moved


              \n" +"This Object may be found here.
              \n" +"
              \n" +msgstr "" +"Document déplacé 302\n" +"

              Objet déplacé


              \n" +"Vous trouverez l'objet recherché ici.
              \n" +"
              \n" + +#. Programmer's name for it: sInvalidISAPIApp +#: Internet/nstois.pas:109 +msgid "Invalid ISAPI application: %s" +msgstr "Application ISAPI invalide: %s" + +#. Programmer's name for it: sUnSupportedISAPIApp +#: Internet/nstois.pas:110 +msgid "Unsupported ISAPI Application version: %.8x" +msgstr "Version de programme ISAPI non supportée: %.8x" + +#. Programmer's name for it: sGEVFailed +#: Internet/nstois.pas:111 +msgid "Call to GetExtensionVersion FAILED. Error Code: %d" +msgstr "L'appel de GetExtensionVersion a échoué. Code erreur: %d" + +#. Programmer's name for it: sErrorLoadingISAPIApp +#: Internet/nstois.pas:112 +msgid "Error loading ISAPI Application: %s" +msgstr "Erreur lors du chargement de l'ISAPI: %s" + +#. Programmer's name for it: sInvalidRedirectParam +#: Internet/nstois.pas:113 +msgid "Invalid Redirect parameter" +msgstr "Paramètre Redirect incorrect" + +#. Programmer's name for it: sISAPIAppError +#: Internet/nstois.pas:114 +msgid "ISAPI Application Error" +msgstr "Erreur d'application ISAPI" + +#. Programmer's name for it: sDataSetFieldBlank +#: Internet/wbmconst.pas:15 +msgid "Data set field is blank" +msgstr "Le champ de dataset est vide." + +#. Programmer's name for it: sDataSetFieldNotFound +#: Internet/wbmconst.pas:16 +msgid "Data set field not found: %s" +msgstr "Champ de dataset non trouvé : %s" + +#. Programmer's name for it: sNotDataSetField +#: Internet/wbmconst.pas:17 +msgid "Field is not a dataset field: %s" +msgstr "Le champ n'est pas un champ de dataset : %s" + +#. Programmer's name for it: ScriptTableName +#: Internet/wbmconst.pas:18 +msgid "%s_Table" +msgstr "%s_Table" + +#. Programmer's name for it: sNoXMLBroker +#: Internet/wbmconst.pas:19 +msgid "%s: missing XMLBroker" +msgstr "%s: il manque XMLBroker" + +#. Programmer's name for it: sFieldNotFound +#: Internet/wbmconst.pas:20 +msgid "%0:s: Field \"%1:s\" not found" +msgstr "%0:s: Champ \"%1:s\" non trouvé" + +#. Programmer's name for it: sXMLBrokerNotDefined +#: Internet/wbmconst.pas:21 +msgid "%s.XMLBroker = nil" +msgstr "%s.XMLBroker = nil" + +#. Programmer's name for it: sSubmitQuery +#: Internet/wbmconst.pas:22 +msgid "Submit" +msgstr "Soumettre" + +#. Programmer's name for it: sResetQuery +#: Internet/wbmconst.pas:23 +msgid "Reset" +msgstr "Réinitialiser" + +#. Programmer's name for it: sApplyUpdates +#: Internet/wbmconst.pas:24 +msgid "Apply Updates" +msgstr "Appliquer les modifications" + +#. Programmer's name for it: sFieldNameBlank +#: Internet/wbmconst.pas:25 +msgid "%s.FieldName = ''" +msgstr "%s.FieldName = ''" + +#. Programmer's name for it: sXMLComponentNotDefined +#: Internet/wbmconst.pas:26 +msgid "%s.XMLComponent = nil" +msgstr "%s.XMLComponent = nil" + +#. Programmer's name for it: ScriptNamesVar +#: Internet/wbmconst.pas:27 +msgid "%s_Names" +msgstr "%s_Names" + +#. Programmer's name for it: ScriptIDsVar +#: Internet/wbmconst.pas:28 +msgid "%s_IDs" +msgstr "%s_IDs" + +#. Programmer's name for it: ScriptXMLDisplayName +#: Internet/wbmconst.pas:29 +msgid "%s_Disp" +msgstr "%s_Display" + +#. Programmer's name for it: sInvalidParent +#: Internet/wbmconst.pas:30 +msgid "Invalid parent" +msgstr "Parent incorrect" + +#. Programmer's name for it: sDuplicateStatusField +#: Internet/wbmconst.pas:31 +msgid "Field %s ignored, only one status field allowed" +msgstr "Champ %s ignoré, un seul champ d'état autorisé" + +#. Programmer's name for it: sFirstButton +#: Internet/wbmconst.pas:32 +msgid "|<" +msgstr "|<" + +#. Programmer's name for it: sLastButton +#: Internet/wbmconst.pas:33 +msgid ">|" +msgstr ">|" + +#. Programmer's name for it: sPriorButton +#: Internet/wbmconst.pas:34 +msgid "<" +msgstr "<" + +#. Programmer's name for it: sNextButton +#: Internet/wbmconst.pas:35 +msgid ">" +msgstr ">" + +#. Programmer's name for it: sPriorPageButton +#: Internet/wbmconst.pas:36 +msgid "<<" +msgstr "<<" + +#. Programmer's name for it: sNextPageButton +#: Internet/wbmconst.pas:37 +msgid ">>" +msgstr ">>" + +#. Programmer's name for it: sDeleteButton +#: Internet/wbmconst.pas:38 +msgid " - " +msgstr " - " + +#. Programmer's name for it: sInsertButton +#: Internet/wbmconst.pas:39 +msgid " + " +msgstr " + " + +#. Programmer's name for it: sUndoButton +#: Internet/wbmconst.pas:40 +msgid "Undo" +msgstr "Défaire" + +#. Programmer's name for it: sPostButton +#: Internet/wbmconst.pas:41 +msgid "Post" +msgstr "Poster" + +#. Programmer's name for it: sWarningsBody +#: Internet/wbmconst.pas:46 +msgid "" +"\n" +"\n" +"

              Design-time Warnings

              \n" +"%s\n" +"

              \n" +msgstr "" +"\n" +"\n" +"

              Avertissements de conception

              \n" +"%s\n" +"

              \n" + +#. Programmer's name for it: ScriptDocumentVarName +#: Internet/wbmconst.pas:47 +msgid "%s_Doc" +msgstr "%s_Doc" + +#. Programmer's name for it: ScriptXMLVarName +#: Internet/wbmconst.pas:48 +msgid "%s_XML" +msgstr "%s_Xml" + +#. Programmer's name for it: sInvalidWebComponentsRegistration +#: Internet/wbmconst.pas:49 +msgid "Invalid Web component registration" +msgstr "Recensement de composant Web incorrect" + +#. Programmer's name for it: sInvalidWebComponentsEnumeration +#: Internet/wbmconst.pas:50 +msgid "Invalid Web component enumeration" +msgstr "Enumération de composant Web incorrecte" + +#. Programmer's name for it: sInvalidWebComponentsCreation +#: Internet/wbmconst.pas:51 +msgid "Invalid Web component creation" +msgstr "Création de composant Web incorrecte" + +#. Programmer's name for it: ScriptRowSetVarName +#: Internet/wbmconst.pas:52 +msgid "%s_RS" +msgstr "%s_RowSet" + +#. Programmer's name for it: sApplyUpdatesError +#: Internet/wbmconst.pas:53 +msgid "ApplyUpdates error. Error count: %d." +msgstr "Erreur ApplyUpdates. Nombre d'erreurs : %d." + +#. Programmer's name for it: sDeltaNotFound +#: Internet/wbmconst.pas:54 +msgid "Missing Delta Packet" +msgstr "Paquet Delta manquant" + +#. Programmer's name for it: sXMLBrokerNotConnected +#: Internet/wbmconst.pas:55 +msgid "XMLBroker: %s is not connected" +msgstr "XMLBroker : %s n'est pas connecté" + +#. Programmer's name for it: sDataSetNotActive +#: Internet/wbmconst.pas:56 +msgid "DataSet: %s is not active" +msgstr "Le dataSet : %s n'est pas actif" + +#. Programmer's name for it: SNewLookupFieldCaption +#: Property Editors/dsdefine.pas:442 +msgid "New Lookup Field" +msgstr "Nouveau champ de recherche" + +#. Programmer's name for it: srSamples +#: Samples/ibconst.pas:6 +msgid "Samples" +msgstr "Exemples" + +#. Programmer's name for it: SNoEventsRegistered +#: Samples/ibconst.pas:7 +msgid "You must register events before queueing them" +msgstr "Vous devez recenser les événements avant de les mettre dans la queue" + +#. Programmer's name for it: SInvalidDBConnection +#: Samples/ibconst.pas:8 +msgid "Component is not connected to an open Database" +msgstr "Le composant n'est pas connecté à une base de données ouverte" + +#. Programmer's name for it: SInvalidDatabase +#: Samples/ibconst.pas:9 +msgid "''%s'' is not connected to an InterBase database" +msgstr "''%s'' n'est pas connecté à une base de données InterBase" + +#. Programmer's name for it: SInvalidCancellation +#: Samples/ibconst.pas:10 +msgid "You cannot call CancelEvents from within an OnEventAlert handler" +msgstr "Vous ne pouvez pas appeler CancelEvents depuis un gestionnaire OnEventAlerterr" + +#. Programmer's name for it: SInvalidEvent +#: Samples/ibconst.pas:11 +msgid "Invalid blank event added to EventAlerter events list" +msgstr "Evénement vide ajouté à la liste d'événements EventAlerter incorrect" + +#. Programmer's name for it: SInvalidQueueing +#: Samples/ibconst.pas:12 +msgid "You cannot call QueueEvents from within an OnEventAlert handler" +msgstr "Vous ne pouvez appeler QueueEvents depuis un gestionnaire OnEventAlerter" + +#. Programmer's name for it: SInvalidRegistration +#: Samples/ibconst.pas:13 +msgid "You cannot Register or Unregister events from within an OnEventAlert handler" +msgstr "Vous ne pouvez appeler Register ou Unregister depuis un gestionnaire OnEventAlerter" + +#. Programmer's name for it: SMaximumEvents +#: Samples/ibconst.pas:13 +msgid "You can only register 15 events per EventAlerter" +msgstr "Vous ne pouvez recenser que 15 événements par EventAlerter" + +#. Programmer's name for it: SInterbaseNotInstalled +#: Samples/ibctrls.pas:103 +msgid "You must have Interbase installed to use this component" +msgstr "InterBase doit être installé pour pouvoir utiliser ce composant" + +#. Programmer's name for it: SFailedQueEvents +#: Samples/ibctrls.pas:104 +msgid "Failed to lookup isc_que_events" +msgstr "Echec de la consultation de isc_que_events" + +#. Programmer's name for it: SFailedInterprete +#: Samples/ibctrls.pas:105 +msgid "Failed to lookup isc_interprete" +msgstr "Echec de la consultation de isc_interprete" + +#. Programmer's name for it: SFailedFree +#: Samples/ibctrls.pas:106 +msgid "Failed to lookup isc_free" +msgstr "Echec de la consultation de isc_free" + +#. Programmer's name for it: SFailedEventBlock +#: Samples/ibctrls.pas:107 +msgid "Failed to lookup isc_event_block" +msgstr "Echec de la consultation de isc_event_block" + +#. Programmer's name for it: SFailedEventCounts +#: Samples/ibctrls.pas:108 +msgid "Failed to lookup isc_event_counts" +msgstr "Echec de la consultation de isc_event_counts" + +#. Programmer's name for it: SFailedCancelEvents +#: Samples/ibctrls.pas:109 +msgid "Failed to lookup isc_cancel_events" +msgstr "Echec de la consultation de isc_cancel_events" + +#. Programmer's name for it: SInvalidEnumValue +#: Vcl/adoconst.pas:15 +msgid "Invalid Enum Value" +msgstr "Valeur enum incorrecte" + +#. Programmer's name for it: SMissingConnection +#: Vcl/adoconst.pas:16 +msgid "Missing Connection or ConnectionString" +msgstr "Connexion ou ConnectionString manquante" + +#. Programmer's name for it: SNoDetailFilter +#: Vcl/adoconst.pas:17 +msgid "Filter property cannot be used for detail tables" +msgstr "La propriété Filter ne peut être utilisée pour les tables détail" + +#. Programmer's name for it: SBookmarksRequired +#: Vcl/adoconst.pas:18 +msgid "Dataset does not support bookmarks, which are required for multi-record data controls" +msgstr "Le dataset ne supporte pas les marques (bookmark), qui sont requises pour les contrôles de données multienregistrement" + +#. Programmer's name for it: SMissingCommandText +#: Vcl/adoconst.pas:19 +msgid "Missing %s property" +msgstr "Propriété %s manquante" + +#. Programmer's name for it: SNoResultSet +#: Vcl/adoconst.pas:20 +msgid "CommandText does not return a result set" +msgstr "CommandText ne renvoie pas un ensemble de résultats" + +#. Programmer's name for it: SADOCreateError +#: Vcl/adoconst.pas:21 +msgid "Error creating object. Please verify that the Microsoft Data Access Components 2.1 (or later) have been properly installed" +msgstr "Erreur à la création de l'objet. Vérifiez que les composants Microsoft Data Access 2.1 (ou supérieur) ont été correctement installés" + +#. Programmer's name for it: SEventsNotSupported +#: Vcl/adoconst.pas:22 +msgid "Events are not supported with server side TableDirect cursors" +msgstr "Les événements ne sont pas supportés avec les curseurs TableDirect côté serveur" + +#. Programmer's name for it: SUsupportedFieldType +#: Vcl/adoconst.pas:23 +msgid "Unsupported field type (%s) in field %s" +msgstr "Type de champ non supporté (%s) dans le champ %s" + +#. Programmer's name for it: SNoMatchingADOType +#: Vcl/adoconst.pas:24 +msgid "No matching ADO data type for %s" +msgstr "Aucun type de données ADO correspondant pour %s" + +#. Programmer's name for it: SConnectionRequired +#: Vcl/adoconst.pas:25 +msgid "A connection component is required for async ExecuteOptions" +msgstr "Un composant connexion est requis pour ExecuteOptions asynchrone" + +#. Programmer's name for it: SCantRequery +#: Vcl/adoconst.pas:26 +msgid "Cannot perform a requery after connection has changed" +msgstr "Ne peut effectuer une requête après que la connexion a changé" + +#. Programmer's name for it: SNoFilterOptions +#: Vcl/adoconst.pas:27 +msgid "FilterOptions are not supported" +msgstr "Les FilterOptions ne sont pas supportées" + +#. Programmer's name for it: SAutoSessionExclusive +#: Vcl/bdeconst.pas:15 +msgid "Cannot enable AutoSessionName property with more than one session on a form or data-module" +msgstr "Impossible d'activer la propriété AutoSessionName avec plus d'une session sur une fiche ou un module de données" + +#. Programmer's name for it: SAutoSessionExists +#: Vcl/bdeconst.pas:16 +msgid "Cannot add a session to the form or data-module while session '%s' has AutoSessionName enabled" +msgstr "Impossible d'ajouter une session à la fiche ou au module de données alors que la session '%s' a AutoSessionName activé" + +#. Programmer's name for it: SAutoSessionActive +#: Vcl/bdeconst.pas:17 +msgid "Cannot modify SessionName while AutoSessionName is enabled" +msgstr "Impossible de modifier SessionName alors que AutoSessionName est activé" + +#. Programmer's name for it: SDuplicateDatabaseName +#: Vcl/bdeconst.pas:18 +msgid "Duplicate database name '%s'" +msgstr "Nom de base de données dupliqué '%s'" + +#. Programmer's name for it: SDuplicateSessionName +#: Vcl/bdeconst.pas:19 +msgid "Duplicate session name '%s'" +msgstr "Nom de session dupliqué '%s'" + +#. Programmer's name for it: SInvalidSessionName +#: Vcl/bdeconst.pas:20 +msgid "Invalid session name %s" +msgstr "Nom de session %s incorrect" + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/bdeconst.pas:21 +msgid "Database name missing" +msgstr "Nom de base de données manquant" + +#. Programmer's name for it: SSessionNameMissing +#: Vcl/bdeconst.pas:22 +msgid "Session name missing" +msgstr "Nom de session manquant" + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/bdeconst.pas:23 +msgid "Cannot perform this operation on an open database" +msgstr "Impossible d'effectuer cette opération sur une table ouverte" + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/bdeconst.pas:24 +msgid "Cannot perform this operation on a closed database" +msgstr "Impossible d'effectuer cette opération sur une table fermée" + +#. Programmer's name for it: SDatabaseHandleSet +#: Vcl/bdeconst.pas:25 +msgid "Database handle owned by a different session" +msgstr "Le handle de base de données appartient à une autre session" + +#. Programmer's name for it: SSessionActive +#: Vcl/bdeconst.pas:26 +msgid "Cannot perform this operation on an active session" +msgstr "Impossible d'effectuer cette opération sur une session active" + +#. Programmer's name for it: SHandleError +#: Vcl/bdeconst.pas:27 +msgid "Error creating cursor handle" +msgstr "Erreur à la création du handle de curseur" + +#. Programmer's name for it: SInvalidFloatField +#: Vcl/bdeconst.pas:28 +msgid "Cannot convert field '%s' to a floating point value" +msgstr "Impossible de convertir le champ '%s' en valeur flottante" + +#. Programmer's name for it: SInvalidIntegerField +#: Vcl/bdeconst.pas:29 +msgid "Cannot convert field '%s' to an integer value" +msgstr "Impossible de convertir le champ '%s' en valeur entière" + +#. Programmer's name for it: STableMismatch +#: Vcl/bdeconst.pas:30 +msgid "Source and destination tables are incompatible" +msgstr "Les tables source et destination sont incompatibles" + +#. Programmer's name for it: SFieldAssignError +#: Vcl/bdeconst.pas:31 +msgid "Fields '%s' and '%s' are not assignment compatible" +msgstr "Les champs '%s' et '%s' ne sont pas compatibles pour une affectation" + +#. Programmer's name for it: SNoReferenceTableName +#: Vcl/bdeconst.pas:32 +msgid "ReferenceTableName not specified for field '%s'" +msgstr "Table de référence non spécifiée pour le champ '%s'" + +#. Programmer's name for it: SCompositeIndexError +#: Vcl/bdeconst.pas:33 +msgid "Cannot use array of Field values with Expression Indices" +msgstr "Impossible d'utiliser de valeurs tableau de champs avec des Indices Expression" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/bdeconst.pas:34 +msgid "Invalid batch move parameters" +msgstr "Paramètres de déplacement batch incorrects" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/bdeconst.pas:35 +msgid "No SQL statement available" +msgstr "Aucune instruction SQL disponible" + +#. Programmer's name for it: SNoParameterValue +#: Vcl/bdeconst.pas:36 +msgid "No value for parameter '%s'" +msgstr "Pas de valeur pour le paramètre '%s'" + +#. Programmer's name for it: SNoParameterType +#: Vcl/bdeconst.pas:37 +msgid "No parameter type for parameter '%s'" +msgstr "Pas de type pour le paramètre '%s'" + +#. Programmer's name for it: SLoginError +#: Vcl/bdeconst.pas:38 +msgid "Cannot connect to database '%s'" +msgstr "Impossible de se connecter à la base '%s'" + +#. Programmer's name for it: SInitError +#: Vcl/bdeconst.pas:39 +msgid "An error occurred while attempting to initialize the Borland Database Engine (error $%.4x)" +msgstr "Une erreur est survenue lors de l'initialisation de Borland Database Engine (erreur $%.4x)" + +#. Programmer's name for it: SDatabaseEditor +#. Programmer's name for it: SIBDatabaseEditor +#: Vcl/bdeconst.pas:40 +msgid "Da&tabase Editor..." +msgstr "Edite&ur base de données..." + +#. Programmer's name for it: SExplore +#: Vcl/bdeconst.pas:41 +msgid "E&xplore" +msgstr "Exp&lorateur" + +#. Programmer's name for it: SLinkDetail +#: Vcl/bdeconst.pas:42 +msgid "'%s' cannot be opened" +msgstr "'%s' ne peut être ouvert" + +#. Programmer's name for it: SLinkMasterSource +#: Vcl/bdeconst.pas:43 +msgid "The MasterSource property of '%s' must be linked to a DataSource" +msgstr "La propriété MasterSource de '%s' doit être liée à une source de données" + +#. Programmer's name for it: SLinkMaster +#: Vcl/bdeconst.pas:44 +msgid "Unable to open the MasterSource Table" +msgstr "Impossible d'ouvrir la table MasterSource" + +#. Programmer's name for it: SGQEVerb +#: Vcl/bdeconst.pas:45 +msgid "S&QL Builder..." +msgstr "Constructeur &SQL..." + +#. Programmer's name for it: SBindVerb +#: Vcl/bdeconst.pas:46 +msgid "Define &Parameters..." +msgstr "Définir les ¶mètres..." + +#. Programmer's name for it: SDisconnectDatabase +#: Vcl/bdeconst.pas:48 +msgid "Database is currently connected. Disconnect and continue?" +msgstr "La base de données est connectée. Déconnecter et continuer ?" + +#. Programmer's name for it: SBDEError +#: Vcl/bdeconst.pas:49 +msgid "BDE error $%.4x" +msgstr "Erreur BDE $%.4x" + +#. Programmer's name for it: SLookupSourceError +#: Vcl/bdeconst.pas:50 +msgid "Unable to use duplicate DataSource and LookupSource" +msgstr "Impossible d'utiliser DataSource et LookupSource dupliqués" + +#. Programmer's name for it: SLookupTableError +#: Vcl/bdeconst.pas:51 +msgid "LookupSource must be connected to TTable component" +msgstr "LookupSource doit être connecté au composant TTable" + +#. Programmer's name for it: SLookupIndexError +#: Vcl/bdeconst.pas:52 +msgid "%s must be the lookup table's active index" +msgstr "%s doit être l'index actif de la table de référence" + +#. Programmer's name for it: SParameterTypes +#: Vcl/bdeconst.pas:53 +msgid ";Input;Output;Input/Output;Result" +msgstr ";Entrée;Sortie;Entrée/Sortie;Résultat" + +#. Programmer's name for it: SInvalidParamFieldType +#: Vcl/bdeconst.pas:54 +msgid "Must have a valid field type selected" +msgstr "Un type de champ correct doit être sélectionné" + +#. Programmer's name for it: STruncationError +#: Vcl/bdeconst.pas:55 +msgid "Parameter '%s' truncated on output" +msgstr "Paramètre '%s' tronqué en sortie" + +#. Programmer's name for it: SDataTypes +#: Vcl/bdeconst.pas:56 +msgid ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" +msgstr ";String;SmallInt;Integer;Word;Boolean;Float;Currency;BCD;Date;Time;DateTime;;;;Blob;Memo;Graphic;;;;;Cursor;" + +#. Programmer's name for it: SResultName +#: Vcl/bdeconst.pas:57 +msgid "Result" +msgstr "Result" + +#. Programmer's name for it: SDBCaption +#: Vcl/bdeconst.pas:58 +msgid "%s%s%s Database" +msgstr "Base de données %s%s%s" + +#. Programmer's name for it: SParamEditor +#: Vcl/bdeconst.pas:59 +msgid "%s%s%s Parameters" +msgstr "Paramètres %s%s%s" + +#. Programmer's name for it: SIndexFilesEditor +#: Vcl/bdeconst.pas:60 +msgid "%s%s%s Index Files" +msgstr "Fichiers index %s%s%s" + +#. Programmer's name for it: SNoIndexFiles +#. Programmer's name for it: srNone +#: Vcl/bdeconst.pas:61 +msgid "(None)" +msgstr "(vide)" + +#. Programmer's name for it: SIndexDoesNotExist +#: Vcl/bdeconst.pas:62 +msgid "Index does not exist. Index: %s" +msgstr "L'index n'existe pas. Index : %s" + +#. Programmer's name for it: SNoTableName +#: Vcl/bdeconst.pas:63 +msgid "Missing TableName property" +msgstr "Propriété TableName manquante" + +#. Programmer's name for it: SNoDataSetField +#: Vcl/bdeconst.pas:64 +msgid "Missing DataSetField property" +msgstr "Propriété DataSetField manquante" + +#. Programmer's name for it: SBatchExecute +#. Programmer's name for it: SExecute +#: Vcl/bdeconst.pas:65 +msgid "E&xecute" +msgstr "Exéc&uter" + +#. Programmer's name for it: SNoCachedUpdates +#: Vcl/bdeconst.pas:66 +msgid "Not in cached update mode" +msgstr "Pas en mode modification cachée" + +#. Programmer's name for it: SInvalidAliasName +#: Vcl/bdeconst.pas:67 +msgid "Invalid alias name %s" +msgstr "Nom d'alias %s incorrect" + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/bdeconst.pas:68 +msgid "Cannot access field '%s' in a filter" +msgstr "Impossible d'accéder au champ '%s' dans un filtre" + +#. Programmer's name for it: SUpdateSQLEditor +#. Programmer's name for it: SIBUpdateSQLEditor +#: Vcl/bdeconst.pas:69 +msgid "&UpdateSQL Editor..." +msgstr "Editeur &UpdateSQL..." + +#. Programmer's name for it: SNoDataSet +#: Vcl/bdeconst.pas:70 +msgid "No dataset association" +msgstr "Il n'y a pas d'association de dataset" + +#. Programmer's name for it: SUntitled +#: Vcl/bdeconst.pas:71 +msgid "Untitled Application" +msgstr "Application sans titre" + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/bdeconst.pas:72 +msgid "Cannot update, %s is not owned by %s" +msgstr "Impossible de mettre à jour, %s n'est pas possédé par %s" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/bdeconst.pas:73 +msgid "Update failed" +msgstr "Echec de la mise à jour" + +#. Programmer's name for it: SSQLGenSelect +#: Vcl/bdeconst.pas:74 +msgid "Must select at least one key field and one update field" +msgstr "Vous devez sélectionner au moins un champ clé et un champ de mise à jour" + +#. Programmer's name for it: SSQLNotGenerated +#: Vcl/bdeconst.pas:75 +msgid "Update SQL statements not generated, exit anyway?" +msgstr "Instructions de mise à jour SQL non générées, quitter quand même ?" + +#. Programmer's name for it: SSQLDataSetOpen +#: Vcl/bdeconst.pas:76 +msgid "Unable to determine field names for %s" +msgstr "Impossible de déterminer les noms de champs pour %s" + +#. Programmer's name for it: SLocalTransDirty +#: Vcl/bdeconst.pas:77 +msgid "The transaction isolation level must be dirty read for local databases" +msgstr "Le niveau d'isolation de transaction doit être Lecture Dirty (dirty read) pour les bases locales" + +#. Programmer's name for it: SMissingDataSet +#: Vcl/bdeconst.pas:78 +msgid "Missing DataSet property" +msgstr "Propriété DataSet manquante" + +#. Programmer's name for it: SNoProvider +#: Vcl/bdeconst.pas:79 +msgid "No provider available" +msgstr "Aucun fournisseur disponible" + +#. Programmer's name for it: SNotAQuery +#: Vcl/bdeconst.pas:80 +msgid "Dataset is not a query" +msgstr "Le dataset n'est pas une requête" + +#. Programmer's name for it: sTabFailClear +#: Vcl/comstrs.pas:15 +msgid "Failed to clear tab control" +msgstr "Echec à l'effacement du contrôle onglet" + +#. Programmer's name for it: sTabFailDelete +#: Vcl/comstrs.pas:16 +msgid "Failed to delete tab at index %d" +msgstr "Echec à la suppression de l'onglet d'indice %d" + +#. Programmer's name for it: sTabFailRetrieve +#: Vcl/comstrs.pas:17 +msgid "Failed to retrieve tab at index %d" +msgstr "Echec à la récupération de l'onglet d'indice %d" + +#. Programmer's name for it: sTabFailGetObject +#: Vcl/comstrs.pas:18 +msgid "Failed to get object at index %d" +msgstr "Echec à l'obtention de l'objet à l'indice %d" + +#. Programmer's name for it: sTabFailSet +#: Vcl/comstrs.pas:19 +msgid "Failed to set tab \"%s\" at index %d" +msgstr "Echec pour mettre l'onglet %s à l'indice %d" + +#. Programmer's name for it: sTabFailSetObject +#: Vcl/comstrs.pas:20 +msgid "Failed to set object at index %d" +msgstr "Echec pour mettre l'objet à l'indice %d" + +#. Programmer's name for it: sTabMustBeMultiLine +#: Vcl/comstrs.pas:21 +msgid "MultiLine must be True when TabPosition is tpLeft or tpRight" +msgstr "MultiLine doit être vrai lorsque TabPosition est tpLeft ou tpRight" + +#. Programmer's name for it: sInvalidLevel +#: Vcl/comstrs.pas:23 +msgid "Invalid item level assignment" +msgstr "Affectation de niveau d'élément incorrecte" + +#. Programmer's name for it: sInvalidLevelEx +#: Vcl/comstrs.pas:24 +msgid "Invalid level (%d) for item \"%s\"" +msgstr "Niveau incorrect (%d) pour l'élément \"%s\"" + +#. Programmer's name for it: sInvalidIndex +#: Vcl/comstrs.pas:25 +msgid "Invalid index" +msgstr "Index incorrect" + +#. Programmer's name for it: sInsertError +#: Vcl/comstrs.pas:26 +msgid "Unable to insert an item" +msgstr "Impossible d'insérer un élément" + +#. Programmer's name for it: sInvalidOwner +#: Vcl/comstrs.pas:28 +msgid "Invalid owner" +msgstr "Propriétaire incorrect" + +#. Programmer's name for it: sUnableToCreateColumn +#: Vcl/comstrs.pas:29 +msgid "Unable to create new column" +msgstr "Impossible de créer une nouvelle colonne" + +#. Programmer's name for it: sUnableToCreateItem +#: Vcl/comstrs.pas:30 +msgid "Unable to create new item" +msgstr "Impossible de créer un nouvel élément" + +#. Programmer's name for it: sRichEditInsertError +#: Vcl/comstrs.pas:32 +msgid "RichEdit line insertion error" +msgstr "Erreur d'insertion de ligne RichEdit" + +#. Programmer's name for it: sRichEditLoadFail +#: Vcl/comstrs.pas:33 +msgid "Failed to Load Stream" +msgstr "Erreur au chargement du flux" + +#. Programmer's name for it: sRichEditSaveFail +#: Vcl/comstrs.pas:34 +msgid "Failed to Save Stream" +msgstr "Erreur à l'enregistrement du flux" + +#. Programmer's name for it: sTooManyPanels +#: Vcl/comstrs.pas:36 +msgid "StatusBar cannot have more than 64 panels" +msgstr "StatusBar ne peut avoir plus de 64 volets" + +#. Programmer's name for it: sHKError +#: Vcl/comstrs.pas:38 +msgid "Error assigning Hot-Key to %s. %s" +msgstr "Erreur d'affectation de raccourci clavier à %s. %s" + +#. Programmer's name for it: sHKInvalid +#: Vcl/comstrs.pas:39 +msgid "Hot-Key is invalid" +msgstr "Raccourci clavier incorrect" + +#. Programmer's name for it: sHKInvalidWindow +#: Vcl/comstrs.pas:40 +msgid "Window is invalid or a child window" +msgstr "Fenêtre incorrecte ou fenêtre enfant" + +#. Programmer's name for it: sHKAssigned +#: Vcl/comstrs.pas:41 +msgid "Hot-Key is assigned to another window" +msgstr "Raccourci clavier affecté à une autre fenêtre" + +#. Programmer's name for it: sUDAssociated +#: Vcl/comstrs.pas:43 +msgid "%s is already associated with %s" +msgstr "%s est déjà associé avec %s" + +#. Programmer's name for it: sPageIndexError +#: Vcl/comstrs.pas:46 +msgid "%d is an invalid PageIndex value. PageIndex must be between 0 and %d" +msgstr "%d est une valeur de PageIndex incorrecte. PageIndex doit être compris entre 0 et %d" + +#. Programmer's name for it: sInvalidComCtl32 +#: Vcl/comstrs.pas:48 +msgid "This control requires version 4.70 or greater of COMCTL32.DLL" +msgstr "Ce contrôle nécessite COMCTL32.DLL version 4.70 ou supérieure" + +#. Programmer's name for it: sDateTimeMax +#: Vcl/comstrs.pas:50 +msgid "Date exceeds maximum of %s" +msgstr "La date dépasse le maximum de %s" + +#. Programmer's name for it: sDateTimeMin +#: Vcl/comstrs.pas:51 +msgid "Date is less than minimum of %s" +msgstr "La date est inférieure au minimum de %s" + +#. Programmer's name for it: sNeedAllowNone +#: Vcl/comstrs.pas:52 +msgid "You must be in ShowCheckbox mode to set to this date" +msgstr "Vous devez être en mode ShowCheckBox pour définir cette date" + +#. Programmer's name for it: sFailSetCalDateTime +#: Vcl/comstrs.pas:53 +msgid "Failed to set calendar date or time" +msgstr "Echec lors du paramétrage de la date ou l'heure du calendrier" + +#. Programmer's name for it: sFailSetCalMaxSelRange +#: Vcl/comstrs.pas:54 +msgid "Failed to set maximum selection range" +msgstr "Echec lors du paramétrage de l'étendue de sélection maximum" + +#. Programmer's name for it: sFailSetCalMinMaxRange +#: Vcl/comstrs.pas:55 +msgid "Failed to set calendar min/max range" +msgstr "Echec lors du paramétrage de l'étendue minimum/maximum du calendrier" + +#. Programmer's name for it: sCalRangeNeedsMultiSelect +#: Vcl/comstrs.pas:56 +msgid "Date range can only be used in multiselect mode" +msgstr "Une étendue de date ne peut être utilisée qu'en mode multisélection" + +#. Programmer's name for it: sFailsetCalSelRange +#: Vcl/comstrs.pas:57 +msgid "Failed to set calendar selected range" +msgstr "Echec lors du paramétrage de l'étendue sélectionnée du calendrier" + +#. Programmer's name for it: SOpenFileTitle +#. IndexFiles..OpenDialog..Title +#: Vcl/consts.pas:15 +msgid "Open" +msgstr "Ouvrir" + +#. Programmer's name for it: SAssignError +#: Vcl/consts.pas:16 +msgid "Cannot assign a %s to a %s" +msgstr "Impossible d'affecter %s à %s" + +#. Programmer's name for it: SFCreateError +#: Vcl/consts.pas:17 +msgid "Cannot create file %s" +msgstr "Impossible de créer le fichier %s" + +#. Programmer's name for it: SFOpenError +#: Vcl/consts.pas:18 +msgid "Cannot open file %s" +msgstr "Impossible d'ouvrir le fichier %s" + +#. Programmer's name for it: SReadError +#: Vcl/consts.pas:19 +msgid "Stream read error" +msgstr "Erreur de lecture du flux" + +#. Programmer's name for it: SWriteError +#: Vcl/consts.pas:20 +msgid "Stream write error" +msgstr "Erreur d'écriture dans le flux" + +#. Programmer's name for it: SMemoryStreamError +#: Vcl/consts.pas:21 +msgid "Out of memory while expanding memory stream" +msgstr "Plus de mémoire lors de l'expansion du flux mémoire" + +#. Programmer's name for it: SCantWriteResourceStreamError +#: Vcl/consts.pas:22 +msgid "Can't write to a read-only resource stream" +msgstr "Impossible d'écrire dans un flux en lecture seule" + +#. Programmer's name for it: SDuplicateReference +#: Vcl/consts.pas:23 +msgid "WriteObject called twice for the same instance" +msgstr "WriteObject appelé deux fois pour la même instance" + +#. Programmer's name for it: SClassNotFound +#: Vcl/consts.pas:24 +msgid "Class %s not found" +msgstr "Classe %s non trouvée" + +#. Programmer's name for it: SInvalidImage +#. Programmer's name for it: SInvalidStreamFormat +#: Vcl/consts.pas:25 +msgid "Invalid stream format" +msgstr "Format de flux incorrect" + +#. Programmer's name for it: SResNotFound +#. Programmer's name for it: sResNotFound +#: Vcl/consts.pas:26 +msgid "Resource %s not found" +msgstr "Ressource %s non trouvée" + +#. Programmer's name for it: SClassMismatch +#: Vcl/consts.pas:27 +msgid "Resource %s is of incorrect class" +msgstr "La ressource %s est d'une classe incorrecte" + +#. Programmer's name for it: SListIndexError +#: Vcl/consts.pas:28 +msgid "List index out of bounds (%d)" +msgstr "Indice de liste hors limites (%d)" + +#. Programmer's name for it: SListCapacityError +#: Vcl/consts.pas:29 +msgid "List capacity out of bounds (%d)" +msgstr "Capacité de liste hors limites (%d)" + +#. Programmer's name for it: SListCountError +#: Vcl/consts.pas:30 +msgid "List count out of bounds (%d)" +msgstr "Compte de liste hors limites (%d)" + +#. Programmer's name for it: SSortedListError +#: Vcl/consts.pas:31 +msgid "Operation not allowed on sorted string list" +msgstr "Opération non autorisée sur une liste de chaînes triée" + +#. Programmer's name for it: SDuplicateString +#: Vcl/consts.pas:32 +msgid "String list does not allow duplicates" +msgstr "La liste de chaînes n'autorise pas les doublons" + +#. Programmer's name for it: SInvalidTabIndex +#: Vcl/consts.pas:33 +msgid "Tab index out of bounds" +msgstr "Indice d'onglet hors limites" + +#. Programmer's name for it: SInvalidTabPosition +#: Vcl/consts.pas:34 +msgid "Tab position incompatible with current tab style" +msgstr "Position d'onglet incompatible avec le style d'onglet actuel" + +#. Programmer's name for it: SInvalidTabStyle +#: Vcl/consts.pas:35 +msgid "Tab style incompatible with current tab position" +msgstr "Style d'onglet incompatible avec la position d'onglet actuelle" + +#. Programmer's name for it: SDuplicateName +#: Vcl/consts.pas:36 +msgid "A component named %s already exists" +msgstr "Un composant nommé %s existe déjà" + +#. Programmer's name for it: SInvalidName +#: Vcl/consts.pas:37 +msgid "''%s'' is not a valid component name" +msgstr "''%s'' n'est pas un nom de composant correct" + +#. Programmer's name for it: SDuplicateClass +#: Vcl/consts.pas:38 +msgid "A class named %s already exists" +msgstr "Une classe nommée %s existe déjà" + +#. Programmer's name for it: SNoComSupport +#: Vcl/consts.pas:39 +msgid "%s has not been registered as a COM class" +msgstr "%s n'a pas été recensé comme classe COM" + +#. Programmer's name for it: SInvalidInteger +#: Vcl/consts.pas:40 +msgid "''%s'' is not a valid integer value" +msgstr "''%s'' n'est pas une valeur entière correcte" + +#. Programmer's name for it: SLineTooLong +#. Programmer's name for it: SOutlineLongLine +#: Vcl/consts.pas:41 +msgid "Line too long" +msgstr "Ligne trop longue" + +#. Programmer's name for it: SInvalidPropertyValue +#. Programmer's name for it: SInvalidProperty +#: Vcl/consts.pas:42 +msgid "Invalid property value" +msgstr "Valeur de propriété incorrecte" + +#. Programmer's name for it: SInvalidPropertyPath +#: Vcl/consts.pas:43 +msgid "Invalid property path" +msgstr "Chemin de propriété incorrect" + +#. Programmer's name for it: SInvalidPropertyType +#: Vcl/consts.pas:44 +msgid "Invalid property type: %s" +msgstr "Type de propriété incorrect : %s" + +#. Programmer's name for it: SInvalidPropertyElement +#: Vcl/consts.pas:45 +msgid "Invalid property element: %s" +msgstr "Elément de propriété incorrect : %s" + +#. Programmer's name for it: SUnknownProperty +#: Vcl/consts.pas:46 +msgid "Property does not exist" +msgstr "Propriété inexistante" + +#. Programmer's name for it: SReadOnlyProperty +#: Vcl/consts.pas:47 +msgid "Property is read-only" +msgstr "Propriété en lecture seule" + +#. Programmer's name for it: SPropertyException +#: Vcl/consts.pas:48 +msgid "Error reading %s%s%s: %s" +msgstr "Erreur lors de la lecture de %s%s%s: %s" + +#. Programmer's name for it: SAncestorNotFound +#: Vcl/consts.pas:49 +msgid "Ancestor for '%s' not found" +msgstr "Ancêtre de '%s' non trouvé" + +#. Programmer's name for it: SInvalidBitmap +#: Vcl/consts.pas:50 +msgid "Bitmap image is not valid" +msgstr "Image bitmap incorrecte" + +#. Programmer's name for it: SInvalidIcon +#: Vcl/consts.pas:51 +msgid "Icon image is not valid" +msgstr "Image icône incorrecte" + +#. Programmer's name for it: SInvalidMetafile +#: Vcl/consts.pas:52 +msgid "Metafile is not valid" +msgstr "MetaFichier incorrect" + +#. Programmer's name for it: SInvalidPixelFormat +#: Vcl/consts.pas:53 +msgid "Invalid pixel format" +msgstr "Format de pixel incorrect" + +#. Programmer's name for it: SBitmapEmpty +#: Vcl/consts.pas:54 +msgid "Bitmap is empty" +msgstr "Bitmap vide" + +#. Programmer's name for it: SScanLine +#: Vcl/consts.pas:55 +msgid "Scan line index out of range" +msgstr "Indice ligne hors limites" + +#. Programmer's name for it: SChangeIconSize +#: Vcl/consts.pas:56 +msgid "Cannot change the size of an icon" +msgstr "Impossible de modifier la taille d'une icône" + +#. Programmer's name for it: SOleGraphic +#: Vcl/consts.pas:57 +msgid "Invalid operation on TOleGraphic" +msgstr "Opération incorrecte sur TOleGraphic" + +#. Programmer's name for it: SUnknownExtension +#: Vcl/consts.pas:58 +msgid "Unknown picture file extension (.%s)" +msgstr "Extension de fichier graphique inconnue (.%s)" + +#. Programmer's name for it: SUnknownClipboardFormat +#: Vcl/consts.pas:59 +msgid "Unsupported clipboard format" +msgstr "Format de Presse-papiers non supporté" + +#. Programmer's name for it: SOutOfResources +#: Vcl/consts.pas:60 +msgid "Out of system resources" +msgstr "Plus de ressources système" + +#. Programmer's name for it: SNoCanvasHandle +#: Vcl/consts.pas:61 +msgid "Canvas does not allow drawing" +msgstr "Le canevas ne permet pas de dessiner" + +#. Programmer's name for it: SInvalidImageSize +#: Vcl/consts.pas:62 +msgid "Invalid image size" +msgstr "Taille d'image incorrecte" + +#. Programmer's name for it: STooManyImages +#: Vcl/consts.pas:63 +msgid "Too many images" +msgstr "Trop d'images" + +#. Programmer's name for it: SDimsDoNotMatch +#: Vcl/consts.pas:64 +msgid "Image dimensions do not match image list dimensions" +msgstr "Les dimensions de l'image ne correspondent pas à celles de la liste d'image" + +#. Programmer's name for it: SInvalidImageList +#: Vcl/consts.pas:65 +msgid "Invalid ImageList" +msgstr "ImageList incorrecte" + +#. Programmer's name for it: SReplaceImage +#: Vcl/consts.pas:66 +msgid "Unable to Replace Image" +msgstr "Impossible de remplacer l'image" + +#. Programmer's name for it: SImageIndexError +#: Vcl/consts.pas:67 +msgid "Invalid ImageList Index" +msgstr "Indice ImageList incorrect" + +#. Programmer's name for it: SImageReadFail +#: Vcl/consts.pas:68 +msgid "Failed to read ImageList data from stream" +msgstr "Erreur à la lecture des données ImageList du flux" + +#. Programmer's name for it: SImageWriteFail +#: Vcl/consts.pas:69 +msgid "Failed to write ImageList data to stream" +msgstr "Erreur à l'écriture des données ImageList dans le flux" + +#. Programmer's name for it: SWindowDCError +#: Vcl/consts.pas:70 +msgid "Error creating window device context" +msgstr "Erreur à la création du contexte périphérique fenêtre" + +#. Programmer's name for it: SClientNotSet +#: Vcl/consts.pas:71 +msgid "Client of TDrag not initialized" +msgstr "Client de TDrag non initialisé" + +#. Programmer's name for it: SWindowClass +#: Vcl/consts.pas:72 +msgid "Error creating window class" +msgstr "Erreur à la création de la classe fenêtre" + +#. Programmer's name for it: SWindowCreate +#: Vcl/consts.pas:73 +msgid "Error creating window" +msgstr "Erreur à la création de fenêtre" + +#. Programmer's name for it: SCannotFocus +#: Vcl/consts.pas:74 +msgid "Cannot focus a disabled or invisible window" +msgstr "Impossible de focaliser une fenêtre désactivée ou invisible" + +#. Programmer's name for it: SParentRequired +#: Vcl/consts.pas:75 +msgid "Control '%s' has no parent window" +msgstr "Le contrôle '%s' n'a pas de fenêtre parente" + +#. Programmer's name for it: SMDIChildNotVisible +#: Vcl/consts.pas:76 +msgid "Cannot hide an MDI Child Form" +msgstr "Impossible de cacher une fiche enfant MDI" + +#. Programmer's name for it: SVisibleChanged +#: Vcl/consts.pas:77 +msgid "Cannot change Visible in OnShow or OnHide" +msgstr "Impossible de changer Visible dans OnShow ou OnHide" + +#. Programmer's name for it: SCannotShowModal +#: Vcl/consts.pas:78 +msgid "Cannot make a visible window modal" +msgstr "Impossible de rendre modale une fenêtre visible" + +#. Programmer's name for it: SScrollBarRange +#: Vcl/consts.pas:79 +msgid "Scrollbar property out of range" +msgstr "Propriété barre de défilement hors limites" + +#. Programmer's name for it: SPropertyOutOfRange +#: Vcl/consts.pas:80 +msgid "%s property out of range" +msgstr "Propriété %s hors limites" + +#. Programmer's name for it: SMenuIndexError +#: Vcl/consts.pas:81 +msgid "Menu index out of range" +msgstr "Indice de menu hors limites" + +#. Programmer's name for it: SMenuReinserted +#: Vcl/consts.pas:82 +msgid "Menu inserted twice" +msgstr "Menu inséré deux fois" + +#. Programmer's name for it: SMenuNotFound +#: Vcl/consts.pas:83 +msgid "Sub-menu is not in menu" +msgstr "Sous-menu pas dans le menu" + +#. Programmer's name for it: SNoTimers +#: Vcl/consts.pas:84 +msgid "Not enough timers available" +msgstr "Pas assez de timers disponibles" + +#. Programmer's name for it: SNotPrinting +#: Vcl/consts.pas:85 +msgid "Printer is not currently printing" +msgstr "L'imprimante n'imprime pas pour l'instant" + +#. Programmer's name for it: SPrinting +#: Vcl/consts.pas:86 +msgid "Printing in progress" +msgstr "Impression en cours" + +#. Programmer's name for it: SPrinterIndexError +#: Vcl/consts.pas:87 +msgid "Printer index out of range" +msgstr "Indice imprimante hors limites" + +#. Programmer's name for it: SInvalidPrinter +#: Vcl/consts.pas:88 +msgid "Printer selected is not valid" +msgstr "Imprimante sélectionnée incorrecte" + +#. Programmer's name for it: SDeviceOnPort +#: Vcl/consts.pas:89 +msgid "%s on %s" +msgstr "%s sur %s" + +#. Programmer's name for it: SGroupIndexTooLow +#: Vcl/consts.pas:90 +msgid "GroupIndex cannot be less than a previous menu item's GroupIndex" +msgstr "GroupIndex ne peut être inférieur à celui de l'élément de menu précédent" + +#. Programmer's name for it: STwoMDIForms +#: Vcl/consts.pas:91 +msgid "Cannot have more than one MDI form per application" +msgstr "Impossible d'avoir plus d'une fiche MDI par application" + +#. Programmer's name for it: SNoMDIForm +#: Vcl/consts.pas:92 +msgid "Cannot create form. No MDI forms are currently active" +msgstr "Impossible de créer la fiche. Aucune fiche Non MDI active" + +#. Programmer's name for it: SRegisterError +#: Vcl/consts.pas:93 +msgid "Invalid component registration" +msgstr "Enregistrement de composant incorrect" + +#. Programmer's name for it: SImageCanvasNeedsBitmap +#: Vcl/consts.pas:94 +msgid "Can only modify an image if it contains a bitmap" +msgstr "Ne peut modifier une image que si elle contient un bitmap" + +#. Programmer's name for it: SControlParentSetToSelf +#: Vcl/consts.pas:95 +msgid "A control cannot have itself as its parent" +msgstr "Un contrôle ne peut avoir lui-même comme parent" + +#. Programmer's name for it: SOKButton +#. Programmer's name for it: SMsgDlgOK +#. DSSCubeEditor..OKButton..Caption +#. DSSQueryEditor..OKButton..Caption +#. ConnEditForm..OkButton..Caption +#. ClientDataForm..OkBtn..Caption +#. DBEditForm..OkButton..Caption +#. AddFields..OkBtn..Caption +#. AssociateAttributes..OKBtn..Caption +#. SaveAttributesAs..OKBtn..Caption +#. DefineField..OkBtn..Caption +#. LinkFields..Button1..Caption +#. IndexFiles..Ok..Caption +#. PictureEditorDlg..OKButton..Caption +#: Vcl/consts.pas:96 +#: Cube/mxdssqry.dfm:321 +#: Property Editors/adoconed.dfm:19 +#: Editors/cdsedit.dfm:39 +#: Editors/dbedit.dfm:140 +#: Editors/dsadd.dfm:24 +#: Editors/dsattra.dfm:18 +#: Editors/dsattrs.dfm:56 +#: Editors/dsdefine.dfm:103 +#: Editors/fldlinks.dfm:141 +#: Editors/ixedit.dfm:64 +#: Editors/picedit.dfm:22 +msgid "OK" +msgstr "OK" + +#. Programmer's name for it: SCancelButton +#. Programmer's name for it: SMsgDlgCancel +#. DSSCubeEditor..CancelButton..Caption +#. DSSQueryEditor..Cancel..Caption +#. ConnEditForm..CancelButton..Caption +#. ClientDataForm..CancelBtn..Caption +#. DBEditForm..CancelButton..Caption +#. InputReqDialog..CancelButton..Caption +#. LoginDialog..CancelButton..Caption +#. AddFields..CancelBtn..Caption +#. AssociateAttributes..CancelBtn..Caption +#. SaveAttributesAs..CancelBtn..Caption +#. DefineField..CancelBtn..Caption +#. LinkFields..Button2..Caption +#. IndexFiles..Cancel..Caption +#. PictureEditorDlg..CancelButton..Caption +#. SQLEditForm..ButtonPanel..CancelButton..Caption +#. StrEditDlg..CancelButton..Caption +#. UpdateSQLEditForm..CancelButton..Caption +#: Vcl/consts.pas:97 +#: Cube/mxdssqry.dfm:311 +#: Property Editors/adoconed.dfm:30 +#: Editors/cdsedit.dfm:52 +#: Editors/dbedit.dfm:152 +#: Editors/dbinpreq.dfm:29 +#: Editors/dblogdlg.dfm:30 +#: Editors/dsadd.dfm:36 +#: Editors/dsattra.dfm:30 +#: Editors/dsattrs.dfm:67 +#: Editors/dsdefine.dfm:115 +#: Editors/fldlinks.dfm:153 +#: Editors/ixedit.dfm:75 +#: Editors/picedit.dfm:33 +#: Editors/sqledit.dfm:106 +#: Editors/stredit.dfm:66 +#: Editors/updsqled.dfm:32 +msgid "Cancel" +msgstr "Annuler" + +#. Programmer's name for it: SYesButton +#. Programmer's name for it: SMsgDlgYes +#: Vcl/consts.pas:98 +msgid "&Yes" +msgstr "&Oui" + +#. Programmer's name for it: SNoButton +#. Programmer's name for it: SMsgDlgNo +#: Vcl/consts.pas:99 +msgid "&No" +msgstr "&Non" + +#. Programmer's name for it: SHelpButton +#. Programmer's name for it: SMsgDlgHelp +#. DSSCubeEditor..HelpButton..Caption +#. DSSQueryEditor..HelpButton..Caption +#. ConnEditForm..HelpButton..Caption +#. ClientDataForm..HelpBtn..Caption +#. DBEditForm..HelpButton..Caption +#. DataBindForm..HelpBtn..Caption +#. AddFields..HelpBtn..Caption +#. AssociateAttributes..HelpBtn..Caption +#. SaveAttributesAs..HelpBtn..Caption +#. DefineField..HelpBtn..Caption +#. LinkFields..Help..Caption +#. IndexFiles..Help..Caption +#. PictureEditorDlg..HelpButton..Caption +#. SQLEditForm..ButtonPanel..HelpButton..Caption +#. StrEditDlg..HelpButton..Caption +#. UpdateSQLEditForm..HelpButton..Caption +#: Vcl/consts.pas:100 +#: Cube/mxdssqry.dfm:331 +#: Property Editors/adoconed.dfm:39 +#: Editors/cdsedit.dfm:61 +#: Editors/dbedit.dfm:161 +#: Editors/dboleedt.dfm:128 +#: Editors/dsadd.dfm:65 +#: Editors/dsattra.dfm:40 +#: Editors/dsattrs.dfm:77 +#: Editors/dsdefine.dfm:124 +#: Editors/fldlinks.dfm:162 +#: Editors/ixedit.dfm:84 +#: Editors/picedit.dfm:42 +#: Editors/sqledit.dfm:116 +#: Editors/stredit.dfm:46 +#: Editors/updsqled.dfm:41 +msgid "&Help" +msgstr "&Aide" + +#. Programmer's name for it: SCloseButton +#. SocketForm..PopupMenu..miClose..Caption +#: Vcl/consts.pas:101 +msgid "&Close" +msgstr "&Fermer" + +#. Programmer's name for it: SIgnoreButton +#. Programmer's name for it: SMsgDlgIgnore +#: Vcl/consts.pas:102 +msgid "&Ignore" +msgstr "I&gnorer" + +#. Programmer's name for it: SRetryButton +#. Programmer's name for it: SMsgDlgRetry +#: Vcl/consts.pas:103 +msgid "&Retry" +msgstr "&Retenter" + +#. Programmer's name for it: SAbortButton +#: Vcl/consts.pas:104 +msgid "Abort" +msgstr "Abandon" + +#. Programmer's name for it: SAllButton +#. Programmer's name for it: SMsgDlgAll +#: Vcl/consts.pas:105 +msgid "&All" +msgstr "&Tout" + +#. Programmer's name for it: SCannotDragForm +#: Vcl/consts.pas:107 +msgid "Cannot drag a form" +msgstr "Impossible de glisser une fiche" + +#. Programmer's name for it: SPutObjectError +#: Vcl/consts.pas:108 +msgid "PutObject to undefined item" +msgstr "PutObject à élément indéfini" + +#. Programmer's name for it: SCardDLLNotLoaded +#: Vcl/consts.pas:109 +msgid "Could not load CARDS.DLL" +msgstr "Impossible de charger CARDS.DLL" + +#. Programmer's name for it: SDuplicateCardId +#: Vcl/consts.pas:110 +msgid "Duplicate CardId found" +msgstr "CardID dupliqué" + +#. Programmer's name for it: SDdeErr +#: Vcl/consts.pas:112 +msgid "An error returned from DDE ($0%x)" +msgstr "Une erreur a été renvoyée par DDE ($0%x)" + +#. Programmer's name for it: SDdeConvErr +#: Vcl/consts.pas:113 +msgid "DDE Error - conversation not established ($0%x)" +msgstr "Erreur DDE - Conversation non établie ($0%x)" + +#. Programmer's name for it: SDdeMemErr +#: Vcl/consts.pas:114 +msgid "Error occurred when DDE ran out of memory ($0%x)" +msgstr "Erreur apparue lorsque DDE manqua de mémoire ($0%x)" + +#. Programmer's name for it: SDdeNoConnect +#: Vcl/consts.pas:115 +msgid "Unable to connect DDE conversation" +msgstr "Impossible de connecter la conversation DDE" + +#. Programmer's name for it: SFB +#: Vcl/consts.pas:117 +msgid "FB" +msgstr "TF" + +#. Programmer's name for it: SFG +#: Vcl/consts.pas:118 +msgid "FG" +msgstr "T" + +#. Programmer's name for it: SBG +#: Vcl/consts.pas:119 +msgid "BG" +msgstr "F" + +#. Programmer's name for it: SOldTShape +#: Vcl/consts.pas:120 +msgid "Cannot load older version of TShape" +msgstr "Impossible de charger version antérieure de TShape" + +#. Programmer's name for it: SVMetafiles +#: Vcl/consts.pas:121 +msgid "Metafiles" +msgstr "MétaFichiers" + +#. Programmer's name for it: SVEnhMetafiles +#: Vcl/consts.pas:122 +msgid "Enhanced Metafiles" +msgstr "MétaFichiers évolués" + +#. Programmer's name for it: SVIcons +#: Vcl/consts.pas:123 +msgid "Icons" +msgstr "Icônes" + +#. Programmer's name for it: SVBitmaps +#: Vcl/consts.pas:124 +msgid "Bitmaps" +msgstr "Bitmaps" + +#. Programmer's name for it: SGridTooLarge +#: Vcl/consts.pas:125 +msgid "Grid too large for operation" +msgstr "Grille trop grande pour l'opération" + +#. Programmer's name for it: STooManyDeleted +#: Vcl/consts.pas:126 +msgid "Too many rows or columns deleted" +msgstr "Trop de lignes ou colonnes supprimées" + +#. Programmer's name for it: SIndexOutOfRange +#: Vcl/consts.pas:127 +msgid "Grid index out of range" +msgstr "Indice de grille hors limites" + +#. Programmer's name for it: SFixedColTooBig +#: Vcl/consts.pas:128 +msgid "Fixed column count must be less than column count" +msgstr "Le nombre de colonnes fixes doit être inférieur au nombre de colonnes" + +#. Programmer's name for it: SFixedRowTooBig +#: Vcl/consts.pas:129 +msgid "Fixed row count must be less than row count" +msgstr "Le nombre de lignes fixes doit être inférieur au nombre de lignes" + +#. Programmer's name for it: SInvalidStringGridOp +#: Vcl/consts.pas:130 +msgid "Cannot insert or delete rows from grid" +msgstr "Impossible d'insérer ou de supprimer les lignes de la grille" + +#. Programmer's name for it: SParseError +#: Vcl/consts.pas:131 +msgid "%s on line %d" +msgstr "%s à la ligne %d" + +#. Programmer's name for it: SIdentifierExpected +#: Vcl/consts.pas:132 +msgid "Identifier expected" +msgstr "Identificateur attendu" + +#. Programmer's name for it: SStringExpected +#: Vcl/consts.pas:133 +msgid "String expected" +msgstr "Chaîne attendue" + +#. Programmer's name for it: SNumberExpected +#: Vcl/consts.pas:134 +msgid "Number expected" +msgstr "Nombre attendu" + +#. Programmer's name for it: SCharExpected +#: Vcl/consts.pas:135 +msgid "''%s'' expected" +msgstr "''%s'' attendu" + +#. Programmer's name for it: SSymbolExpected +#: Vcl/consts.pas:136 +msgid "%s expected" +msgstr "%s attendu" + +#. Programmer's name for it: SInvalidNumber +#: Vcl/consts.pas:137 +msgid "Invalid numeric value" +msgstr "Valeur numérique incorrecte" + +#. Programmer's name for it: SInvalidString +#: Vcl/consts.pas:138 +msgid "Invalid string constant" +msgstr "Constante chaîne incorrecte" + +#. Programmer's name for it: SInvalidBinary +#: Vcl/consts.pas:140 +msgid "Invalid binary value" +msgstr "Valeur binaire incorrecte" + +#. Programmer's name for it: SOutlineIndexError +#: Vcl/consts.pas:141 +msgid "Outline index not found" +msgstr "Indice arborescence non trouvé" + +#. Programmer's name for it: SOutlineExpandError +#: Vcl/consts.pas:142 +msgid "Parent must be expanded" +msgstr "Le parent doit être développé" + +#. Programmer's name for it: SInvalidCurrentItem +#: Vcl/consts.pas:143 +msgid "Invalid value for current item" +msgstr "Valeur incorrecte pour l'élément en cours" + +#. Programmer's name for it: SMaskErr +#: Vcl/consts.pas:144 +msgid "Invalid input value" +msgstr "Valeur d'entrée incorrecte" + +#. Programmer's name for it: SMaskEditErr +#: Vcl/consts.pas:145 +msgid "Invalid input value. Use escape key to abandon changes" +msgstr "Valeur d'entrée incorrecte. Utiliser Echap pour abandonner les modifications" + +#. Programmer's name for it: SOutlineError +#: Vcl/consts.pas:146 +msgid "Invalid outline index" +msgstr "Indice arborescence incorrect" + +#. Programmer's name for it: SOutlineBadLevel +#: Vcl/consts.pas:147 +msgid "Incorrect level assignment" +msgstr "Affectation de niveau incorrect" + +#. Programmer's name for it: SOutlineSelection +#: Vcl/consts.pas:148 +msgid "Invalid selection" +msgstr "Sélection incorrecte" + +#. Programmer's name for it: SOutlineFileLoad +#: Vcl/consts.pas:149 +msgid "File load error" +msgstr "Erreur chargement de fichier" + +#. Programmer's name for it: SOutlineMaxLevels +#: Vcl/consts.pas:151 +msgid "Maximum outline depth exceeded" +msgstr "Profondeur maximum arborescence dépassée" + +#. Programmer's name for it: SMsgDlgWarning +#: Vcl/consts.pas:153 +msgid "Warning" +msgstr "Avertissement" + +#. Programmer's name for it: SMsgDlgError +#: Vcl/consts.pas:154 +msgid "Error" +msgstr "Erreur" + +#. Programmer's name for it: SMsgDlgInformation +#: Vcl/consts.pas:155 +msgid "Information" +msgstr "Information" + +#. Programmer's name for it: SMsgDlgConfirm +#: Vcl/consts.pas:156 +msgid "Confirm" +msgstr "Confirmation" + +#. Programmer's name for it: SMsgDlgHelpNone +#: Vcl/consts.pas:162 +msgid "No help available" +msgstr "Aucune aide disponible" + +#. Programmer's name for it: SMsgDlgHelpHelp +#: Vcl/consts.pas:163 +msgid "Help" +msgstr "Aide" + +#. Programmer's name for it: SMsgDlgAbort +#: Vcl/consts.pas:164 +msgid "&Abort" +msgstr "&Abandon" + +#. Programmer's name for it: SMsgDlgNoToAll +#: Vcl/consts.pas:168 +msgid "N&o to All" +msgstr "Non &pour tout" + +#. Programmer's name for it: SMsgDlgYesToAll +#: Vcl/consts.pas:169 +msgid "Yes to &All" +msgstr "O&ui pour tout" + +#. Programmer's name for it: SmkcBkSp +#: Vcl/consts.pas:171 +msgid "BkSp" +msgstr "RetArr" + +#. Programmer's name for it: SmkcTab +#: Vcl/consts.pas:172 +msgid "Tab" +msgstr "Tab" + +#. Programmer's name for it: SmkcEsc +#: Vcl/consts.pas:173 +msgid "Esc" +msgstr "Echap" + +#. Programmer's name for it: SmkcEnter +#: Vcl/consts.pas:174 +msgid "Enter" +msgstr "Entrée" + +#. Programmer's name for it: SmkcSpace +#: Vcl/consts.pas:175 +msgid "Space" +msgstr "Espace" + +#. Programmer's name for it: SmkcPgUp +#: Vcl/consts.pas:176 +msgid "PgUp" +msgstr "PagePréc" + +#. Programmer's name for it: SmkcPgDn +#: Vcl/consts.pas:177 +msgid "PgDn" +msgstr "PageSuiv" + +#. Programmer's name for it: SmkcEnd +#: Vcl/consts.pas:178 +msgid "End" +msgstr "Fin" + +#. Programmer's name for it: SmkcHome +#: Vcl/consts.pas:179 +msgid "Home" +msgstr "Origine" + +#. Programmer's name for it: SmkcLeft +#: Vcl/consts.pas:180 +msgid "Left" +msgstr "Gauche" + +#. Programmer's name for it: SmkcUp +#: Vcl/consts.pas:181 +msgid "Up" +msgstr "Haut" + +#. Programmer's name for it: SmkcRight +#: Vcl/consts.pas:182 +msgid "Right" +msgstr "Droite" + +#. Programmer's name for it: SmkcDown +#: Vcl/consts.pas:183 +msgid "Down" +msgstr "Bas" + +#. Programmer's name for it: SmkcIns +#: Vcl/consts.pas:184 +msgid "Ins" +msgstr "Ins" + +#. Programmer's name for it: SmkcDel +#: Vcl/consts.pas:185 +msgid "Del" +msgstr "Suppr" + +#. Programmer's name for it: SmkcShift +#: Vcl/consts.pas:186 +msgid "Shift+" +msgstr "Maj+" + +#. Programmer's name for it: SmkcCtrl +#: Vcl/consts.pas:187 +msgid "Ctrl+" +msgstr "Ctrl+" + +#. Programmer's name for it: SmkcAlt +#: Vcl/consts.pas:188 +msgid "Alt+" +msgstr "Alt+" + +#. Programmer's name for it: srUnknown +#. Programmer's name for it: SHostUnknown +#: Vcl/consts.pas:190 +msgid "(Unknown)" +msgstr "(inconnu)" + +#. Programmer's name for it: SOutOfRange +#: Vcl/consts.pas:192 +msgid "Value must be between %d and %d" +msgstr "La valeur doit être comprise entre %d et %d" + +#. Programmer's name for it: SCannotCreateName +#: Vcl/consts.pas:193 +msgid "Cannot create a default method name for an unnamed component" +msgstr "Impossible de créer un nom de méthode par défaut pour un composant sans nom" + +#. Programmer's name for it: SDateEncodeError +#: Vcl/consts.pas:195 +msgid "Invalid argument to date encode" +msgstr "Argument incorrect pour l'encodage de date" + +#. Programmer's name for it: STimeEncodeError +#: Vcl/consts.pas:196 +msgid "Invalid argument to time encode" +msgstr "Argument incorrect pour l'encodage d'heure" + +#. Programmer's name for it: SInvalidDate +#: Vcl/consts.pas:197 +msgid "''%s'' is not a valid date" +msgstr "''%s'' n'est pas une date correcte" + +#. Programmer's name for it: SInvalidTime +#: Vcl/consts.pas:198 +msgid "''%s'' is not a valid time" +msgstr "''%s'' n'est pas une heure correcte" + +#. Programmer's name for it: SInvalidDateTime +#: Vcl/consts.pas:199 +msgid "''%s'' is not a valid date and time" +msgstr "''%s'' n'est pas une date et heure correcte" + +#. Programmer's name for it: SInvalidFileName +#: Vcl/consts.pas:200 +msgid "Invalid file name - %s" +msgstr "Nom de fichier incorrect - %s" + +#. Programmer's name for it: SDefaultFilter +#: Vcl/consts.pas:201 +msgid "All files (*.*)|*.*" +msgstr "Tous les fichiers (*.*)|*.*" + +#. Programmer's name for it: sAllFilter +#: Vcl/consts.pas:202 +msgid "All" +msgstr "Tout" + +#. Programmer's name for it: SNoVolumeLabel +#: Vcl/consts.pas:203 +msgid ": [ - no volume label - ]" +msgstr ": [ Pas de nom de volume ]" + +#. Programmer's name for it: SInsertLineError +#: Vcl/consts.pas:204 +msgid "Unable to insert a line" +msgstr "Impossible d'insérer une ligne" + +#. Programmer's name for it: SConfirmCreateDir +#: Vcl/consts.pas:206 +msgid "The specified directory does not exist. Create it?" +msgstr "Le répertoire spécifié n'existe pas. Le créer ?" + +#. Programmer's name for it: SSelectDirCap +#: Vcl/consts.pas:207 +msgid "Select Directory" +msgstr "Sélection du répertoire" + +#. Programmer's name for it: SCannotCreateDir +#: Vcl/consts.pas:208 +msgid "Unable to create directory" +msgstr "Impossible de créer le répertoire" + +#. Programmer's name for it: SDirNameCap +#: Vcl/consts.pas:209 +msgid "Directory &Name:" +msgstr "&Nom de répertoire :" + +#. Programmer's name for it: SDrivesCap +#: Vcl/consts.pas:210 +msgid "D&rives:" +msgstr "&Lecteurs :" + +#. Programmer's name for it: SDirsCap +#: Vcl/consts.pas:211 +msgid "&Directories:" +msgstr "&Répertoires :" + +#. Programmer's name for it: SFilesCap +#: Vcl/consts.pas:212 +msgid "&Files: (*.*)" +msgstr "&Fichiers : (*.*)" + +#. Programmer's name for it: SNetworkCap +#: Vcl/consts.pas:213 +msgid "Ne&twork..." +msgstr "Ré&seau..." + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:215 +msgid "Color" +msgstr "Couleur" + +#. !! obsolete - delete in 5.0 +#: Vcl/consts.pas:216 +msgid "ABCDEFGHIJKLMNOP" +msgstr "ABCDEFGHIJKLMNOP" + +#. Programmer's name for it: SInvalidClipFmt +#: Vcl/consts.pas:218 +msgid "Invalid clipboard format" +msgstr "Format de Presse-papiers incorrect" + +#. Programmer's name for it: SIconToClipboard +#: Vcl/consts.pas:219 +msgid "Clipboard does not support Icons" +msgstr "Le Presse-papiers ne supporte pas les icônes" + +#. Programmer's name for it: SCannotOpenClipboard +#: Vcl/consts.pas:220 +msgid "Cannot open clipboard" +msgstr "Ne peut ouvrir le Presse-papiers" + +#. Programmer's name for it: SDefault +#. Programmer's name for it: sHTTPItemDefault +#. SQLWindow..DBGrid1..TitleFont.Name +#. DSSQueryEditor..Pager..Dimensions..AddAgg..Font.Name +#: Vcl/consts.pas:222 +#: Cube/mxdssqry.dfm:193 +msgid "Default" +msgstr "Défaut" + +#. Programmer's name for it: SInvalidMemoSize +#: Vcl/consts.pas:224 +msgid "Text exceeds memo capacity" +msgstr "Le texte dépasse la capacité du mémo" + +#. Programmer's name for it: SCustomColors +#: Vcl/consts.pas:225 +msgid "Custom Colors" +msgstr "Couleurs personnalisées" + +#. Programmer's name for it: SInvalidPrinterOp +#: Vcl/consts.pas:226 +msgid "Operation not supported on selected printer" +msgstr "Opération non supportée par l'imprimante sélectionnée" + +#. Programmer's name for it: SNoDefaultPrinter +#: Vcl/consts.pas:227 +msgid "There is no default printer currently selected" +msgstr "Aucune imprimante par défaut sélectionnée" + +#. Programmer's name for it: SIniFileWriteError +#: Vcl/consts.pas:229 +msgid "Unable to write to %s" +msgstr "Impossible d'écrire dans %s" + +#. Programmer's name for it: SBitsIndexError +#: Vcl/consts.pas:231 +msgid "Bits index out of range" +msgstr "Indice de bits hors limites" + +#. Programmer's name for it: SUntitled +#: Vcl/consts.pas:233 +msgid "(Untitled)" +msgstr "(sans titre)" + +#. Programmer's name for it: SInvalidRegType +#: Vcl/consts.pas:235 +msgid "Invalid data type for '%s'" +msgstr "Type de données incorrect pour '%s'" + +#. Programmer's name for it: SRegCreateFailed +#: Vcl/consts.pas:236 +msgid "Failed to create key %s" +msgstr "Echec à la création de la clé %s" + +#. Programmer's name for it: SRegSetDataFailed +#: Vcl/consts.pas:237 +msgid "Failed to set data for '%s'" +msgstr "Echec à la définition des données pour '%s'" + +#. Programmer's name for it: SRegGetDataFailed +#: Vcl/consts.pas:238 +msgid "Failed to get data for '%s'" +msgstr "Echec à l'obtention des données pour '%s'" + +#. Programmer's name for it: SUnknownConversion +#: Vcl/consts.pas:240 +msgid "Unknown RichEdit conversion file extension (.%s)" +msgstr "Extension de fichier de conversion RichEdit inconnue (.%s)" + +#. Programmer's name for it: SDuplicateMenus +#: Vcl/consts.pas:241 +msgid "Menu '%s' is already being used by another form" +msgstr "Le menu '%s' est déjà utilisé par une autre fiche" + +#. Programmer's name for it: SPictureLabel +#: Vcl/consts.pas:243 +msgid "Picture:" +msgstr "Image :" + +#. Programmer's name for it: SPictureDesc +#: Vcl/consts.pas:244 +msgid " (%dx%d)" +msgstr " (%dx%d)" + +#. Programmer's name for it: SPreviewLabel +#: Vcl/consts.pas:245 +msgid "Preview" +msgstr "Prévisualiser" + +#. Programmer's name for it: SCannotOpenAVI +#: Vcl/consts.pas:247 +msgid "Cannot open AVI" +msgstr "Impossible d'ouvrir l'AVI" + +#. Programmer's name for it: SNotOpenErr +#: Vcl/consts.pas:249 +msgid "No MCI device open" +msgstr "Aucun périphérique MCI ouvert" + +#. Programmer's name for it: SMPOpenFilter +#: Vcl/consts.pas:250 +msgid "All files (*.*)|*.*|Wave files (*.wav)|*.wav|Midi files (*.mid)|*.mid|Video for Windows (*.avi)|*.avi" +msgstr "Tous les fichiers (*.*)|*.*|Fichiers wave (*.wav)|*.wav|Fichiers Midi (*.mid)|*.mid|Vidéo pour Windows (*.avi)|*.avi" + +#. Programmer's name for it: SMCIAVIVideo +#: Vcl/consts.pas:252 +msgid "AVIVideo" +msgstr "AVIVideo" + +#. Programmer's name for it: SMCICDAudio +#: Vcl/consts.pas:253 +msgid "CDAudio" +msgstr "CDAudio" + +#. Programmer's name for it: SMCIDAT +#: Vcl/consts.pas:254 +msgid "DAT" +msgstr "DAT" + +#. Programmer's name for it: SMCIDigitalVideo +#: Vcl/consts.pas:255 +msgid "DigitalVideo" +msgstr "DigitalVideo" + +#. Programmer's name for it: SMCIMMMovie +#: Vcl/consts.pas:256 +msgid "MMMovie" +msgstr "MMMovie" + +#. Programmer's name for it: SMCIOther +#: Vcl/consts.pas:257 +msgid "Other" +msgstr "Autre" + +#. Programmer's name for it: SMCIOverlay +#: Vcl/consts.pas:258 +msgid "Overlay" +msgstr "Overlay" + +#. Programmer's name for it: SMCIScanner +#: Vcl/consts.pas:259 +msgid "Scanner" +msgstr "Scanner" + +#. Programmer's name for it: SMCISequencer +#: Vcl/consts.pas:260 +msgid "Sequencer" +msgstr "Séquenceur" + +#. Programmer's name for it: SMCIVCR +#: Vcl/consts.pas:261 +msgid "VCR" +msgstr "Magnétoscope" + +#. Programmer's name for it: SMCIVideodisc +#: Vcl/consts.pas:262 +msgid "Videodisc" +msgstr "Vidéodisque" + +#. Programmer's name for it: SMCIWaveAudio +#: Vcl/consts.pas:263 +msgid "WaveAudio" +msgstr "Audio wav" + +#. Programmer's name for it: SMCIUnknownError +#: Vcl/consts.pas:264 +msgid "Unknown error code" +msgstr "Code d'erreur inconnu" + +#. Programmer's name for it: SBoldItalicFont +#: Vcl/consts.pas:266 +msgid "Bold Italic" +msgstr "Gras Italique" + +#. Programmer's name for it: SBoldFont +#: Vcl/consts.pas:267 +msgid "Bold" +msgstr "Gras" + +#. Programmer's name for it: SItalicFont +#: Vcl/consts.pas:268 +msgid "Italic" +msgstr "Italique" + +#. Programmer's name for it: SRegularFont +#: Vcl/consts.pas:269 +msgid "Regular" +msgstr "Normal" + +#. Programmer's name for it: SPropertiesVerb +#. SocketForm..Pages..PropPage..Caption +#: Vcl/consts.pas:271 +msgid "Properties" +msgstr "Propriétés" + +#. Programmer's name for it: sWindowsSocketError +#: Vcl/consts.pas:273 +msgid "Windows socket error: %s (%d), on API '%s'" +msgstr "Erreur socket Windows : %s (%d), avec l'API '%s'" + +#. Programmer's name for it: sAsyncSocketError +#: Vcl/consts.pas:274 +msgid "Asynchronous socket error %d" +msgstr "Erreur socket asynchrone %d" + +#. Programmer's name for it: sNoAddress +#: Vcl/consts.pas:275 +msgid "No address specified" +msgstr "Aucune adresse spécifiée" + +#. Programmer's name for it: sCannotListenOnOpen +#: Vcl/consts.pas:276 +msgid "Can't listen on an open socket" +msgstr "Ne peut écouter sur un socket ouvert" + +#. Programmer's name for it: sCannotCreateSocket +#: Vcl/consts.pas:277 +msgid "Can't create new socket" +msgstr "Ne peut créer le nouveau socket" + +#. Programmer's name for it: sSocketAlreadyOpen +#: Vcl/consts.pas:278 +msgid "Socket already open" +msgstr "Socket déjà ouvert" + +#. Programmer's name for it: sCantChangeWhileActive +#: Vcl/consts.pas:279 +msgid "Can't change value while socket is active" +msgstr "Ne peut modifier la valeur lorsque le socket est actif" + +#. Programmer's name for it: sSocketMustBeBlocking +#: Vcl/consts.pas:280 +msgid "Socket must be in blocking mode" +msgstr "Le socket doit être en mode bloquant" + +#. Programmer's name for it: sSocketIOError +#: Vcl/consts.pas:281 +msgid "%s error %d, %s" +msgstr "%s erreur %d, %s" + +#. Programmer's name for it: sSocketRead +#. Programmer's name for it: SReadAccess +#: Vcl/consts.pas:282 +msgid "Read" +msgstr "Lecture" + +#. Programmer's name for it: sSocketWrite +#. Programmer's name for it: SWriteAccess +#: Vcl/consts.pas:283 +msgid "Write" +msgstr "Ecriture" + +#. Programmer's name for it: SServiceFailed +#: Vcl/consts.pas:285 +msgid "Service failed on %s: %s" +msgstr "Le service a échoué pour %s : %s" + +#. Programmer's name for it: SExecute +#: Vcl/consts.pas:286 +msgid "execute" +msgstr "exécuter" + +#. Programmer's name for it: SStart +#: Vcl/consts.pas:287 +msgid "start" +msgstr "lancer" + +#. Programmer's name for it: SStop +#: Vcl/consts.pas:288 +msgid "stop" +msgstr "arrêter" + +#. Programmer's name for it: SPause +#: Vcl/consts.pas:289 +msgid "pause" +msgstr "pause" + +#. Programmer's name for it: SContinue +#: Vcl/consts.pas:290 +msgid "continue" +msgstr "continuer" + +#. Programmer's name for it: SInterrogate +#: Vcl/consts.pas:291 +msgid "interrogate" +msgstr "interroger" + +#. Programmer's name for it: SShutdown +#: Vcl/consts.pas:292 +msgid "shutdown" +msgstr "terminer" + +#. Programmer's name for it: SCustomError +#: Vcl/consts.pas:293 +msgid "Service failed in custom message(%d): %s" +msgstr "Le service a échoué dans le message personnalisée (%d) : %s" + +#. Programmer's name for it: SServiceInstallOK +#: Vcl/consts.pas:294 +msgid "Service installed successfully" +msgstr "Service installé avec succès" + +#. Programmer's name for it: SServiceInstallFailed +#: Vcl/consts.pas:295 +msgid "Service \"%s\" failed to install with error: \"%s\"" +msgstr "Le service \"%s\" a échoué pendant son installation avec l'erreur : \"%s\"" + +#. Programmer's name for it: SServiceUninstallOK +#: Vcl/consts.pas:296 +msgid "Service uninstalled successfully" +msgstr "Service désinstallé avec succès" + +#. Programmer's name for it: SServiceUninstallFailed +#: Vcl/consts.pas:297 +msgid "Service \"%s\" failed to uninstall with error: \"%s\"" +msgstr "Le service \"%s\" a échoué pendant sa désinstallation avec l'erreur : \"%s\"" + +#. Programmer's name for it: SInvalidActionRegistration +#: Vcl/consts.pas:299 +msgid "Invalid action registration" +msgstr "Enregistrement d'action incorrecte" + +#. Programmer's name for it: SInvalidActionUnregistration +#: Vcl/consts.pas:300 +msgid "Invalid action unregistration" +msgstr "Désenregistrement d'action incorrecte" + +#. Programmer's name for it: SInvalidActionEnumeration +#: Vcl/consts.pas:301 +msgid "Invalid action enumeration" +msgstr "Enumération d'action incorrecte" + +#. Programmer's name for it: SInvalidActionCreation +#: Vcl/consts.pas:302 +msgid "Invalid action creation" +msgstr "Création d'action incorrecte" + +#. Programmer's name for it: SDockedCtlNeedsName +#: Vcl/consts.pas:304 +msgid "Docked control must have a name" +msgstr "Le composant arrimé doit avoir un nom" + +#. Programmer's name for it: SDockTreeRemoveError +#: Vcl/consts.pas:305 +msgid "Error removing control from dock tree" +msgstr "Erreur à la suppression du contrôle de l'arbre arrimé" + +#. Programmer's name for it: SDockZoneNotFound +#: Vcl/consts.pas:306 +msgid " - Dock zone not found" +msgstr " - Zone d'arrimage non trouvée" + +#. Programmer's name for it: SDockZoneHasNoCtl +#: Vcl/consts.pas:307 +msgid " - Dock zone has no control" +msgstr " - La zone d'arrimage n'a pas de contrôle" + +#. Programmer's name for it: SAllCommands +#: Vcl/consts.pas:309 +msgid "All Commands" +msgstr "Toutes les commandes" + +#. Programmer's name for it: SDuplicateItem +#: Vcl/consts.pas:311 +msgid "List does not allow duplicates ($0%x)" +msgstr "La liste n'autorise pas les doublons ($0%x)" + +#. Programmer's name for it: SDuplicatePropertyCategory +#: Vcl/consts.pas:313 +msgid "A property category called %s already exists" +msgstr "Une catégorie de propriété nommée %s existe déjà" + +#. Programmer's name for it: SUnknownPropertyCategory +#: Vcl/consts.pas:314 +msgid "Property category does not exist (%s)" +msgstr "La catégorie de propriété n'existe pas (%s)" + +#. Programmer's name for it: SActionCategoryName +#: Vcl/consts.pas:316 +msgid "Action" +msgstr "Action" + +#. Programmer's name for it: SActionCategoryDesc +#: Vcl/consts.pas:317 +msgid "Action properties and/or events" +msgstr "Propriétés et/ou événements Action" + +#. Programmer's name for it: SDataCategoryName +#: Vcl/consts.pas:318 +msgid "Data" +msgstr "Données" + +#. Programmer's name for it: SDataCategoryDesc +#: Vcl/consts.pas:319 +msgid "Data properties and/or events" +msgstr "Evénements et/ou événements Données" + +#. Programmer's name for it: SDatabaseCategoryName +#: Vcl/consts.pas:320 +msgid "Database" +msgstr "Base de données" + +#. Programmer's name for it: SDatabaseCategoryDesc +#: Vcl/consts.pas:321 +msgid "Database and Data Aware properties and/or events" +msgstr "Propriétés et/ou événements Base de données et Orientées données" + +#. Programmer's name for it: SDragNDropCategoryName +#: Vcl/consts.pas:322 +msgid "Drag, Drop and Docking" +msgstr "Glisser, Déplacer et Arrimer" + +#. Programmer's name for it: SDragNDropCategoryDesc +#: Vcl/consts.pas:323 +msgid "Drag, Drop and Docking properties and/or events" +msgstr "Propriétés et/ou événements Glisser, Déplacer et Arrimer" + +#. Programmer's name for it: SHelpCategoryName +#: Vcl/consts.pas:324 +msgid "Help and Hints" +msgstr "Aide et Conseil" + +#. Programmer's name for it: SHelpCategoryDesc +#: Vcl/consts.pas:325 +msgid "Help and Hint properties and/or events" +msgstr "Propriétés et/ou événements Aide et Conseil" + +#. Programmer's name for it: SLayoutCategoryName +#: Vcl/consts.pas:326 +msgid "Layout" +msgstr "Disposition" + +#. Programmer's name for it: SLayoutCategoryDesc +#: Vcl/consts.pas:327 +msgid "Layout properties and/or events" +msgstr "Propriétés et/ou événements Disposition" + +#. Programmer's name for it: SLegacyCategoryName +#: Vcl/consts.pas:328 +msgid "Legacy" +msgstr "Legs" + +#. Programmer's name for it: SLegacyCategoryDesc +#: Vcl/consts.pas:329 +msgid "Legacy properties and/or events" +msgstr "Propriétés et/ou événements Legs" + +#. Programmer's name for it: SLinkageCategoryName +#: Vcl/consts.pas:330 +msgid "Linkage" +msgstr "Liaison" + +#. Programmer's name for it: SLinkageCategoryDesc +#: Vcl/consts.pas:331 +msgid "Linkage properties and/or events" +msgstr "Propriétés et/ou événements Liaison" + +#. Programmer's name for it: SLocaleCategoryName +#: Vcl/consts.pas:332 +msgid "Locale" +msgstr "Locale" + +#. Programmer's name for it: SLocaleCategoryDesc +#: Vcl/consts.pas:333 +msgid "Locale properties and/or events" +msgstr "Propriétés et/ou événements Locale" + +#. Programmer's name for it: SLocalizableCategoryName +#: Vcl/consts.pas:334 +msgid "Localizable" +msgstr "Localisable" + +#. Programmer's name for it: SLocalizableCategoryDesc +#: Vcl/consts.pas:335 +msgid "Localizable properties and/or events" +msgstr "Propriétés et/ou événements Localisable" + +#. Programmer's name for it: SMiscellaneousCategoryName +#: Vcl/consts.pas:336 +msgid "Miscellaneous" +msgstr "Divers" + +#. Programmer's name for it: SMiscellaneousCategoryDesc +#: Vcl/consts.pas:337 +msgid "Miscellaneous properties and/or events" +msgstr "Propriétés et/ou événements Divers" + +#. Programmer's name for it: SVisualCategoryName +#: Vcl/consts.pas:338 +msgid "Visual" +msgstr "Visuel" + +#. Programmer's name for it: SVisualCategoryDesc +#: Vcl/consts.pas:339 +msgid "Visual properties and/or events" +msgstr "Propriétés et/ou événements Visuel" + +#. Programmer's name for it: SInputCategoryName +#: Vcl/consts.pas:340 +msgid "Input" +msgstr "Entrée" + +#. Programmer's name for it: SInputCategoryDesc +#: Vcl/consts.pas:341 +msgid "Input properties and/or events" +msgstr "Propriétés et/ou événements Entrée" + +#. Programmer's name for it: SInvalidMask +#: Vcl/consts.pas:343 +msgid "'%s' is an invalid mask at (%d)" +msgstr "'%s' est un masque incorrect à (%d)" + +#. Programmer's name for it: SInvalidFilter +#: Vcl/consts.pas:344 +msgid "Property filters may only be name, class or type based (%d:%d)" +msgstr "Les filtres de propriétés ne peuvent être basés que sur nom, classe ou type (%d:%d)" + +#. Programmer's name for it: SInvalidCategory +#: Vcl/consts.pas:345 +msgid "Categories must define their own name and description" +msgstr "Les catégories doivent définir leur propre nom et description" + +#. Programmer's name for it: sOperationNotAllowed +#: Vcl/consts.pas:347 +msgid "Operation not allowed while dispatching application events" +msgstr "Opération non autorisée lors de la répartition des événements de l'application" + +#. Programmer's name for it: sInvalidClassReference +#: Vcl/ctlpanel.pas:129 +msgid "Invalid class reference for TAppletApplication" +msgstr "Référence de classe incorrecte pour TAppletApplication" + +#. Programmer's name for it: SInvalidFieldSize +#: Vcl/dbconsts.pas:15 +msgid "Invalid field size" +msgstr "Taille de champ incorrecte" + +#. Programmer's name for it: SInvalidFieldKind +#: Vcl/dbconsts.pas:16 +msgid "Invalid FieldKind" +msgstr "FieldKind incorrect" + +#. Programmer's name for it: SInvalidFieldRegistration +#: Vcl/dbconsts.pas:17 +msgid "Invalid field registration" +msgstr "Enregistrement de champ incorrect" + +#. Programmer's name for it: SUnknownFieldType +#: Vcl/dbconsts.pas:18 +msgid "Field '%s' is of an unknown type" +msgstr "Le champ '%s' est d'un type inconnu" + +#. Programmer's name for it: SFieldNameMissing +#: Vcl/dbconsts.pas:19 +msgid "Field name missing" +msgstr "Nom de champ manquant" + +#. Programmer's name for it: SDuplicateFieldName +#: Vcl/dbconsts.pas:20 +msgid "Duplicate field name '%s'" +msgstr "Nom de champ dupliqué '%s'" + +#. Programmer's name for it: SFieldNotFound +#: Vcl/dbconsts.pas:21 +msgid "Field '%s' not found" +msgstr "Champ '%s' non trouvé" + +#. Programmer's name for it: SFieldAccessError +#: Vcl/dbconsts.pas:22 +msgid "Cannot access field '%s' as type %s" +msgstr "Impossible d'accéder au champ '%s' comme type %s" + +#. Programmer's name for it: SFieldValueError +#: Vcl/dbconsts.pas:23 +msgid "Invalid value for field '%s'" +msgstr "Valeur incorrecte pour le champ '%s'" + +#. Programmer's name for it: SFieldRangeError +#: Vcl/dbconsts.pas:24 +msgid "%g is not a valid value for field '%s'. The allowed range is %g to %g" +msgstr "%g n'est pas une valeur correcte pour le champ '%s'. Les valeurs doivent être comprises entre %g et %g" + +#. Programmer's name for it: SInvalidIntegerValue +#: Vcl/dbconsts.pas:25 +msgid "'%s' is not a valid integer value for field '%s'" +msgstr "'%s' n'est pas une valeur entière correcte pour le champ '%s'" + +#. Programmer's name for it: SInvalidBoolValue +#: Vcl/dbconsts.pas:26 +msgid "'%s' is not a valid boolean value for field '%s'" +msgstr "'%s' n'est pas une valeur booléenne correcte pour le champ '%s'" + +#. Programmer's name for it: SInvalidFloatValue +#: Vcl/dbconsts.pas:27 +msgid "'%s' is not a valid floating point value for field '%s'" +msgstr "'%s' n'est pas une valeur flottante correcte pour le champ '%s'" + +#. Programmer's name for it: SFieldTypeMismatch +#: Vcl/dbconsts.pas:28 +msgid "Type mismatch for field '%s', expecting: %s actual: %s" +msgstr "Type inadéquat pour le champ '%s', attendu : %s actuel : %s" + +#. Programmer's name for it: SFieldSizeMismatch +#: Vcl/dbconsts.pas:29 +msgid "Size mismatch for field '%s', expecting: %d actual: %d" +msgstr "Taille inadéquate pour le champ '%s', attendu : %d actuel : %d" + +#. Programmer's name for it: SInvalidVarByteArray +#: Vcl/dbconsts.pas:30 +msgid "Invalid variant type or size for field '%s'" +msgstr "Type ou taille de variant incorrect pour le champ '%s'" + +#. Programmer's name for it: SFieldOutOfRange +#: Vcl/dbconsts.pas:31 +msgid "Value of field '%s' is out of range" +msgstr "La valeur du champ '%s' est hors limites" + +#. Programmer's name for it: SBCDOverflow +#: Vcl/dbconsts.pas:32 +msgid "(Overflow)" +msgstr "(débordement)" + +#. Programmer's name for it: SFieldRequired +#: Vcl/dbconsts.pas:33 +msgid "Field '%s' must have a value" +msgstr "Le champ '%s' doit avoir une valeur" + +#. Programmer's name for it: SDataSetMissing +#: Vcl/dbconsts.pas:34 +msgid "Field '%s' has no dataset" +msgstr "Le champ '%s' n'a pas de DataSet" + +#. Programmer's name for it: SInvalidCalcType +#: Vcl/dbconsts.pas:35 +msgid "Field '%s' cannot be a calculated or lookup field" +msgstr "Le champ '%s' ne peut être un champ calculé ni lookup" + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/dbconsts.pas:36 +msgid "Field '%s' cannot be modified" +msgstr "Le champ '%s' ne peut être modifié" + +#. Programmer's name for it: SFieldIndexError +#: Vcl/dbconsts.pas:37 +msgid "Field index out of range" +msgstr "Index de champ hors limites" + +#. Programmer's name for it: SNoFieldIndexes +#: Vcl/dbconsts.pas:38 +msgid "No index currently active" +msgstr "Aucun index actif actuellement" + +#. Programmer's name for it: SNotIndexField +#: Vcl/dbconsts.pas:39 +msgid "Field '%s' is not indexed and cannot be modified" +msgstr "Le champ '%s' n'est pas indexé et ne peut être modifié" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/dbconsts.pas:40 +msgid "Cannot access index field '%s'" +msgstr "Impossible d'accéder au champ index '%s'" + +#. Programmer's name for it: SDuplicateIndexName +#: Vcl/dbconsts.pas:41 +msgid "Duplicate index name '%s'" +msgstr "Nom d'index dupliqué '%s'" + +#. Programmer's name for it: SNoIndexForFields +#: Vcl/dbconsts.pas:42 +msgid "No index for fields '%s'" +msgstr "Pas d'index pour les champs '%s'" + +#. Programmer's name for it: SIndexNotFound +#: Vcl/dbconsts.pas:43 +msgid "Index '%s' not found" +msgstr "Index '%s' non trouvé" + +#. Programmer's name for it: SDuplicateName +#: Vcl/dbconsts.pas:44 +msgid "Duplicate name '%s' in %s" +msgstr "Nom '%s' dupliqué dans %s" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/dbconsts.pas:45 +msgid "Circular datalinks are not allowed" +msgstr "Liaisons de données circulaires non autorisées" + +#. Programmer's name for it: SLookupInfoError +#: Vcl/dbconsts.pas:46 +msgid "Lookup information for field '%s' is incomplete" +msgstr "Information de référence pour le champ '%s' incomplète" + +#. Programmer's name for it: SDataSourceChange +#: Vcl/dbconsts.pas:47 +msgid "DataSource cannot be changed" +msgstr "DataSource ne peut être modifié" + +#. Programmer's name for it: SNoNestedMasterSource +#: Vcl/dbconsts.pas:48 +msgid "Nested datasets cannot have a MasterSource" +msgstr "Les datasets imbriqués ne peuvent avoir de MasterSource" + +#. Programmer's name for it: SDataSetOpen +#: Vcl/dbconsts.pas:49 +msgid "Cannot perform this operation on an open dataset" +msgstr "Impossible d'effectuer cette opération sur un ensemble de données ouvert" + +#. Programmer's name for it: SNotEditing +#: Vcl/dbconsts.pas:50 +msgid "Dataset not in edit or insert mode" +msgstr "L'ensemble de données n'est pas en mode Edition ou Insertion" + +#. Programmer's name for it: SDataSetClosed +#: Vcl/dbconsts.pas:51 +msgid "Cannot perform this operation on a closed dataset" +msgstr "Impossible d'effectuer cette opération sur un ensemble de données fermé" + +#. Programmer's name for it: SDataSetEmpty +#: Vcl/dbconsts.pas:52 +msgid "Cannot perform this operation on an empty dataset" +msgstr "Impossible d'effectuer cette opération sur un ensemble de données vide" + +#. Programmer's name for it: SDataSetReadOnly +#: Vcl/dbconsts.pas:53 +msgid "Cannot modify a read-only dataset" +msgstr "Impossible de modifier un ensemble de données en lecture seule" + +#. Programmer's name for it: SNestedDataSetClass +#: Vcl/dbconsts.pas:54 +msgid "Nested dataset must inherit from %s" +msgstr "Le dataset imbriqué doit hériter de %s" + +#. Programmer's name for it: SExprTermination +#: Vcl/dbconsts.pas:55 +msgid "Filter expression incorrectly terminated" +msgstr "Expression filtre terminée incorrectement" + +#. Programmer's name for it: SExprNameError +#: Vcl/dbconsts.pas:56 +msgid "Unterminated field name" +msgstr "Nom de champ non terminé" + +#. Programmer's name for it: SExprStringError +#: Vcl/dbconsts.pas:57 +msgid "Unterminated string constant" +msgstr "Constante chaîne non terminée" + +#. Programmer's name for it: SExprInvalidChar +#: Vcl/dbconsts.pas:58 +msgid "Invalid filter expression character: '%s'" +msgstr "Caractère d'expression filtre incorrect : '%s'" + +#. Programmer's name for it: SExprNoLParen +#: Vcl/dbconsts.pas:59 +msgid "'(' expected but %s found" +msgstr "'(' attendu mais %s trouvé" + +#. Programmer's name for it: SExprNoRParen +#: Vcl/dbconsts.pas:60 +msgid "')' expected but %s found" +msgstr "')' attendu mais %s trouvé" + +#. Programmer's name for it: SExprNoRParenOrComma +#: Vcl/dbconsts.pas:61 +msgid "')' or ',' expected but %s found" +msgstr "')' ou ',' attendu mais %s trouvé" + +#. Programmer's name for it: SExprExpected +#: Vcl/dbconsts.pas:62 +msgid "Expression expected but %s found" +msgstr "Expression attendue mais %s trouvé" + +#. Programmer's name for it: SExprBadField +#: Vcl/dbconsts.pas:63 +msgid "Field '%s' cannot be used in a filter expression" +msgstr "Le champ '%s' ne peut être utilisé dans une expression filtre" + +#. Programmer's name for it: SExprBadNullTest +#: Vcl/dbconsts.pas:64 +msgid "NULL only allowed with '=' and '<>'" +msgstr "NULL autorisé seulement avec '=' et '<>'" + +#. Programmer's name for it: SExprRangeError +#: Vcl/dbconsts.pas:65 +msgid "Constant out of range" +msgstr "Constante hors limites" + +#. Programmer's name for it: SExprNotBoolean +#: Vcl/dbconsts.pas:66 +msgid "Field '%s' is not of type Boolean" +msgstr "Le champ '%s' n'est pas de type BOOLEAN" + +#. Programmer's name for it: SExprIncorrect +#: Vcl/dbconsts.pas:67 +msgid "Incorrectly formed filter expression" +msgstr "Expression filtre formée incorrectement" + +#. Programmer's name for it: SExprNothing +#: Vcl/dbconsts.pas:68 +msgid "nothing" +msgstr "vide" + +#. Programmer's name for it: SExprTypeMis +#: Vcl/dbconsts.pas:69 +msgid "Type mismatch in expression" +msgstr "Non concordance de type dans l'expression" + +#. Programmer's name for it: SExprBadScope +#: Vcl/dbconsts.pas:70 +msgid "Operation cannot mix aggregate value with record-varying value" +msgstr "L'opération ne peut grouper une valeur globale avec une valeur variant par enregistrement" + +#. Programmer's name for it: SExprNoArith +#: Vcl/dbconsts.pas:71 +msgid "Arithmetic in filter expressions not supported" +msgstr "Arithmétique non supportée dans les expressions filtre" + +#. Programmer's name for it: SExprNotAgg +#: Vcl/dbconsts.pas:72 +msgid "Expression is not an aggregate expression" +msgstr "L'expression n'est pas une expression globale" + +#. Programmer's name for it: SExprBadConst +#: Vcl/dbconsts.pas:73 +msgid "Constant is not correct type %s" +msgstr "La constante n'est pas du type correct %s" + +#. Programmer's name for it: SExprNoAggFilter +#: Vcl/dbconsts.pas:74 +msgid "Aggregate expressions not allowed in filters" +msgstr "Les expressions globales ne sont pas autorisées dans les filtres" + +#. Programmer's name for it: SExprEmptyInList +#: Vcl/dbconsts.pas:75 +msgid "IN predicate list may not be empty" +msgstr "La liste de prédicats IN ne peut être vide" + +#. Programmer's name for it: SInvalidKeywordUse +#: Vcl/dbconsts.pas:76 +msgid "Invalid use of keyword" +msgstr "Utilisation incorrecte du mot clé" + +#. Programmer's name for it: SParameterNotFound +#: Vcl/dbconsts.pas:79 +msgid "Parameter '%s' not found" +msgstr "Paramètres '%s' non trouvés" + +#. Programmer's name for it: SInvalidVersion +#: Vcl/dbconsts.pas:80 +msgid "Unable to load bind parameters" +msgstr "Impossible de charger les paramètres de liaison" + +#. Programmer's name for it: SParamTooBig +#: Vcl/dbconsts.pas:81 +msgid "Parameter '%s', cannot save data larger than %d bytes" +msgstr "Le paramètre '%s' ne peut enregistrer des données de plus de %d octets" + +#. Programmer's name for it: SBadFieldType +#: Vcl/dbconsts.pas:82 +msgid "Field '%s' is of an unsupported type" +msgstr "Le champ '%s' est d'un type non supporté" + +#. Programmer's name for it: SAggActive +#: Vcl/dbconsts.pas:83 +msgid "Property may not be modified while aggregate is active" +msgstr "La propriété ne peut être modifiée lorsque aggregate est actif" + +#. Programmer's name for it: SProviderSQLNotSupported +#: Vcl/dbconsts.pas:84 +msgid "SQL not supported: %s" +msgstr "SQL non supporté : %s" + +#. Programmer's name for it: SProviderExecuteNotSupported +#: Vcl/dbconsts.pas:85 +msgid "Execute not supported: %s" +msgstr "Execute non supporté : %s" + +#. Programmer's name for it: SExprNoAggOnCalcs +#: Vcl/dbconsts.pas:86 +msgid "Field '%s' is not the correct type of calculated field to be used in an aggregate, use an internalcalc" +msgstr "Le champ '%s' n'est pas le type correct de champ calculé à utiliser dans un agrégat, utilisez un CalcInterne" + +#. Programmer's name for it: SRecordChanged +#: Vcl/dbconsts.pas:87 +msgid "Record changed by another user" +msgstr "Enregistrement modifié par un autre utilisateur" + +#. Programmer's name for it: SFirstRecord +#: Vcl/dbconsts.pas:90 +msgid "First record" +msgstr "Premier enregistrement" + +#. Programmer's name for it: SPriorRecord +#: Vcl/dbconsts.pas:91 +msgid "Prior record" +msgstr "Enregistrement précédent" + +#. Programmer's name for it: SNextRecord +#: Vcl/dbconsts.pas:92 +msgid "Next record" +msgstr "Enregistrement suivant" + +#. Programmer's name for it: SLastRecord +#: Vcl/dbconsts.pas:93 +msgid "Last record" +msgstr "Dernier enregistrement" + +#. Programmer's name for it: SInsertRecord +#: Vcl/dbconsts.pas:94 +msgid "Insert record" +msgstr "Insérer enregistrement" + +#. Programmer's name for it: SDeleteRecord +#: Vcl/dbconsts.pas:95 +msgid "Delete record" +msgstr "Supprimer enregistrement" + +#. Programmer's name for it: SEditRecord +#: Vcl/dbconsts.pas:96 +msgid "Edit record" +msgstr "Modifier enregistrement" + +#. Programmer's name for it: SPostEdit +#: Vcl/dbconsts.pas:97 +msgid "Post edit" +msgstr "Valider modifications" + +#. Programmer's name for it: SCancelEdit +#: Vcl/dbconsts.pas:98 +msgid "Cancel edit" +msgstr "Annuler modifications" + +#. Programmer's name for it: SRefreshRecord +#: Vcl/dbconsts.pas:99 +msgid "Refresh data" +msgstr "Rafraîchir données" + +#. Programmer's name for it: SDeleteRecordQuestion +#: Vcl/dbconsts.pas:100 +msgid "Delete record?" +msgstr "Supprimer l'enregistrement ?" + +#. Programmer's name for it: SDeleteMultipleRecordsQuestion +#: Vcl/dbconsts.pas:101 +msgid "Delete all selected records?" +msgstr "Supprimer tous les enregistrements sélectionnés ?" + +#. Programmer's name for it: SRecordNotFound +#: Vcl/dbconsts.pas:102 +msgid "Record not found" +msgstr "Enregistrement non trouvé" + +#. Programmer's name for it: SDataSourceFixed +#: Vcl/dbconsts.pas:103 +msgid "Operation not allowed in a DBCtrlGrid" +msgstr "Opération non autorisée dans un DBCtrlGrid" + +#. Programmer's name for it: SNotReplicatable +#: Vcl/dbconsts.pas:104 +msgid "Control cannot be used in a DBCtrlGrid" +msgstr "Le contrôle ne peut être utilisé dans un DBCtrlGrid" + +#. Programmer's name for it: SPropDefByLookup +#: Vcl/dbconsts.pas:105 +msgid "Property already defined by lookup field" +msgstr "Propriété déjà définie dans un DBCtrlGrid" + +#. Programmer's name for it: STooManyColumns +#: Vcl/dbconsts.pas:106 +msgid "Grid requested to display more than 256 columns" +msgstr "La grille nécessitait d'afficher plus de 256 colonnes" + +#. Programmer's name for it: SRemoteLogin +#: Vcl/dbconsts.pas:109 +msgid "Remote Login" +msgstr "Connexion distante" + +#. Programmer's name for it: SDataBindings +#: Vcl/dbconsts.pas:112 +msgid "Data Bindings..." +msgstr "Liaisons de données..." + +#. Programmer's name for it: SIBTransactionEditor +#: Vcl/ib.pas:156 +msgid "&Transaction Editor..." +msgstr "Editeur de &transaction..." + +#. Programmer's name for it: SDatabaseFilter +#: Vcl/ib.pas:157 +msgid "Database Files (*.gdb)|*.gdb|All files (*.*)|*.*" +msgstr "Fichiers bases de données (*.gdb)|*.gdb|Tous les fichiers (*.*)|*.*" + +#. Programmer's name for it: SCommitTransaction +#: Vcl/ib.pas:159 +msgid "Transaction is currently Active. Rollback and continue?" +msgstr "Transaction actuellement active. Rollback et continuer ?" + +#. Programmer's name for it: SUnknownError +#: Vcl/ib.pas:168 +msgid "Unknown error" +msgstr "Erreur inconnue." + +#. Programmer's name for it: SInterBaseMissing +#: Vcl/ib.pas:169 +msgid "InterBase library gds32.dll not found in the path. Please install InterBase to use this functionality" +msgstr "DLL InterBase gds32.dll non trouvée dans le chemin" + +#. Programmer's name for it: SInterBaseInstallMissing +#: Vcl/ib.pas:170 +msgid "InterBase Install DLL ibinstall.dll not found in the path. Please install InterBase 6 to use this functionality" +msgstr "DLL d'installation InterBase ibinstall.dll non trouvée dans le chemin. Veuillez installer InterBase 6 pour cette fonctionnalité" + +#. Programmer's name for it: SIB60feature +#: Vcl/ib.pas:171 +msgid "%s is an InterBase6 function. Please upgrade to InterBase6 to use this functonality" +msgstr "%s est une fonction spécifique IB 6. Passez à IB6 pour utiliser cette fonctionnalité" + +#. Programmer's name for it: SNotSupported +#: Vcl/ib.pas:172 +msgid "Unsupported feature" +msgstr "Fonctionnalité non supportée." + +#. Programmer's name for it: SNotPermitted +#: Vcl/ib.pas:173 +msgid "Not permitted" +msgstr "Non permis." + +#. Programmer's name for it: SFileAccessError +#: Vcl/ib.pas:174 +msgid "Temporary file access error" +msgstr "Erreur d'accès au fichier temporaire." + +#. Programmer's name for it: SConnectionTimeout +#: Vcl/ib.pas:175 +msgid "Database connection timed out" +msgstr "La connexion base de données a dépassé le temps imparti." + +#. Programmer's name for it: SCannotSetDatabase +#: Vcl/ib.pas:176 +msgid "Cannot set database" +msgstr "Ne peut définir la base de données." + +#. Programmer's name for it: SCannotSetTransaction +#: Vcl/ib.pas:177 +msgid "Cannot set transaction" +msgstr "Ne peut définir la transaction." + +#. Programmer's name for it: SOperationCancelled +#: Vcl/ib.pas:178 +msgid "Operation cancelled at user's request" +msgstr "Opération annulée à la demande de l'utilisateur." + +#. Programmer's name for it: SDPBConstantNotSupported +#: Vcl/ib.pas:179 +msgid "DPB Constant (isc_dpb_%s) is unsupported" +msgstr "Constante DPB (isc_dpb_%s) non supportée." + +#. Programmer's name for it: SDPBConstantUnknown +#: Vcl/ib.pas:180 +msgid "DPB Constant (%d) is unknown" +msgstr "Constante DPB (%d) inconnue." + +#. Programmer's name for it: STPBConstantNotSupported +#: Vcl/ib.pas:181 +msgid "TPB Constant (isc_tpb_%s) is unsupported" +msgstr "Constante TPB (isc_tpb_%s) non supportée." + +#. Programmer's name for it: STPBConstantUnknown +#: Vcl/ib.pas:182 +msgid "TPB Constant (%d) is unknown" +msgstr "Constante TPB (%d) inconnue." + +#. Programmer's name for it: SDatabaseClosed +#: Vcl/ib.pas:183 +msgid "Cannot perform operation -- DB is not open" +msgstr "Ne peut effectuer l'opération -- La base n'est pas ouverte." + +#. Programmer's name for it: SDatabaseOpen +#: Vcl/ib.pas:184 +msgid "Cannot perform operation -- DB is currently open" +msgstr "Ne peut effectuer l'opération -- La base est actuellement ouverte." + +#. Programmer's name for it: SDatabaseNameMissing +#: Vcl/ib.pas:185 +msgid "Database name is missing" +msgstr "Le nom de base de données est manquant." + +#. Programmer's name for it: SNotInTransaction +#: Vcl/ib.pas:186 +msgid "Transaction is not active" +msgstr "La transaction n'est pas active." + +#. Programmer's name for it: SInTransaction +#: Vcl/ib.pas:187 +msgid "Transaction is active" +msgstr "La transaction est active." + +#. Programmer's name for it: STimeoutNegative +#: Vcl/ib.pas:188 +msgid "Timeout values cannot be negative" +msgstr "Les valeurs de délai imparti ne peuvent être négatives." + +#. Programmer's name for it: SNoDatabasesInTransaction +#: Vcl/ib.pas:189 +msgid "No databases are listed in transaction component" +msgstr "Aucune base de données listée dans le composant transaction." + +#. Programmer's name for it: SUpdateWrongDB +#: Vcl/ib.pas:190 +msgid "Updating wrong database" +msgstr "Mise à jour de la mauvaise base de données." + +#. Programmer's name for it: SUpdateWrongTR +#: Vcl/ib.pas:191 +msgid "Updating wrong transaction. Unique transaction expected in set" +msgstr "Mise à jour de la mauvaise transaction. Transaction unique attendue dans le set" + +#. Programmer's name for it: SDatabaseNotAssigned +#: Vcl/ib.pas:192 +msgid "Database not assigned" +msgstr "Base de données non affectée." + +#. Programmer's name for it: STransactionNotAssigned +#: Vcl/ib.pas:193 +msgid "Transaction not assigned" +msgstr "Transaction non affectée." + +#. Programmer's name for it: SXSQLDAIndexOutOfRange +#: Vcl/ib.pas:194 +msgid "XSQLDA index out of range" +msgstr "Index XSQLDA hors limites." + +#. Programmer's name for it: SXSQLDANameDoesNotExist +#: Vcl/ib.pas:195 +msgid "XSQLDA name does not exist (%s)" +msgstr "Nom XSQLDA inexistant (%s)." + +#. Programmer's name for it: SEOF +#: Vcl/ib.pas:196 +msgid "End of file" +msgstr "Fin de fichier." + +#. Programmer's name for it: SBOF +#: Vcl/ib.pas:197 +msgid "Beginning of file" +msgstr "Début du fichier." + +#. Programmer's name for it: SInvalidStatementHandle +#: Vcl/ib.pas:198 +msgid "Invalid statement handle" +msgstr "Handle d'instruction incorrect." + +#. Programmer's name for it: SSQLOpen +#: Vcl/ib.pas:199 +msgid "IBSQL Open" +msgstr "IBSQL ouvert" + +#. Programmer's name for it: SSQLClosed +#: Vcl/ib.pas:200 +msgid "IBSQL Closed" +msgstr "IBSQL fermé" + +#. Programmer's name for it: SDatasetOpen +#: Vcl/ib.pas:201 +msgid "Dataset open" +msgstr "Dataset ouvert." + +#. Programmer's name for it: SDatasetClosed +#: Vcl/ib.pas:202 +msgid "Dataset closed" +msgstr "Dataset fermé." + +#. Programmer's name for it: SUnknownSQLDataType +#: Vcl/ib.pas:203 +msgid "Unknown SQL Data type (%d)" +msgstr "Type de données SQL inconnu (%d)." + +#. Programmer's name for it: SInvalidColumnIndex +#: Vcl/ib.pas:204 +msgid "Invalid column index (index exceeds permitted range)" +msgstr "indice de colonne incorrect (il dépasse les limites)." + +#. Programmer's name for it: SInvalidParamColumnIndex +#: Vcl/ib.pas:205 +msgid "Invalid parameter index (index exceeds permitted range)" +msgstr "Indice de paramètre incorrect (il dépasse les limites)." + +#. Programmer's name for it: SInvalidDataConversion +#: Vcl/ib.pas:206 +msgid "Invalid data conversion" +msgstr "Conversion de données incorrecte." + +#. Programmer's name for it: SColumnIsNotNullable +#: Vcl/ib.pas:207 +msgid "Column cannot be set to null (%s)" +msgstr "La colonne ne peut être définie à null (%s)" + +#. Programmer's name for it: SBlobCannotBeRead +#: Vcl/ib.pas:208 +msgid "Blob stream cannot be read" +msgstr "Ne peut lire dans le flux blob." + +#. Programmer's name for it: SBlobCannotBeWritten +#: Vcl/ib.pas:209 +msgid "Blob stream cannot be written" +msgstr "Ne peut écrire dans le flux blob." + +#. Programmer's name for it: SEmptyQuery +#: Vcl/ib.pas:210 +msgid "Empty query" +msgstr "Requête vide." + +#. Programmer's name for it: SCannotOpenNonSQLSelect +#: Vcl/ib.pas:211 +msgid "Cannot \"open\" a non-select statement. Use ExecQuery" +msgstr "Ne peut ouvrir (open) une instruction non sélectionnée. Utilisez ExecQuery." + +#. Programmer's name for it: SNoFieldAccess +#: Vcl/ib.pas:212 +msgid "No access to field \"%s\"" +msgstr "Pas d'accès au champ %s." + +#. Programmer's name for it: SFieldReadOnly +#: Vcl/ib.pas:213 +msgid "Field \"%s\" is read-only" +msgstr "Champ %s en lecture-seule." + +#. Programmer's name for it: SFieldNotFound +#: Vcl/ib.pas:214 +msgid "Field \"%s\" not found" +msgstr "Champ %s non trouvé." + +#. Programmer's name for it: SNotEditing +#: Vcl/ib.pas:215 +msgid "Not editing" +msgstr "Pas en édition." + +#. Programmer's name for it: SCannotInsert +#: Vcl/ib.pas:216 +msgid "Cannot insert into dataset. (No insert query)" +msgstr "Ne peut insérer dans le dataset. (pas de requête insert)." + +#. Programmer's name for it: SCannotPost +#: Vcl/ib.pas:217 +msgid "Cannot post. (No update/insert query)" +msgstr "Ne peut poster. (pas de requête update/insert)." + +#. Programmer's name for it: SCannotUpdate +#: Vcl/ib.pas:218 +msgid "Cannot update. (No update query)" +msgstr "Ne peut mettre à jour. (pas de requête update)." + +#. Programmer's name for it: SCannotDelete +#: Vcl/ib.pas:219 +msgid "Cannot delete from dataset. (No delete query)" +msgstr "Ne peut supprimer depuis le dataset. (pas de requête delete)." + +#. Programmer's name for it: SCannotRefresh +#: Vcl/ib.pas:220 +msgid "Cannot refresh row. (No refresh query)" +msgstr "Ne peut rafraîchir la ligne. (pas de requête refresh)." + +#. Programmer's name for it: SBufferNotSet +#: Vcl/ib.pas:221 +msgid "Buffer not set" +msgstr "Tampon non défini." + +#. Programmer's name for it: SCircularReference +#: Vcl/ib.pas:222 +msgid "Circular references not permitted" +msgstr "Références circulaires non autorisées" + +#. Programmer's name for it: SSQLParseError +#: Vcl/ib.pas:223 +msgid "" +"SQL Parse Error:\n" +"\n" +"%s" +msgstr "" +"Erreur analyse SQL :\n" +"\n" +"%s" + +#. Programmer's name for it: SUserAbort +#: Vcl/ib.pas:224 +msgid "User abort" +msgstr "Abandon par l'utilisateur." + +#. Programmer's name for it: SDataSetUniDirectional +#: Vcl/ib.pas:225 +msgid "Data set is uni-directional" +msgstr "Le Dataset est uni-directionnel." + +#. Programmer's name for it: SCannotCreateSharedResource +#: Vcl/ib.pas:226 +msgid "Cannot create shared resource. (Windows error %d)" +msgstr "Ne peut créer la ressource partagée. (Erreur Windows %d)" + +#. Programmer's name for it: SWindowsAPIError +#: Vcl/ib.pas:227 +msgid "Windows API error. (Windows error %d [$%.8x])" +msgstr "Erreur de l'API Windows. (Erreur Windows %d [$%.8x])" + +#. Programmer's name for it: SColumnListsDontMatch +#: Vcl/ib.pas:228 +msgid "Column lists do not match" +msgstr "Les listes de colonnes ne correspondent pas." + +#. Programmer's name for it: SColumnTypesDontMatch +#: Vcl/ib.pas:229 +msgid "Column types don't match. (From index: %d; To index: %d)" +msgstr "Les types de colonnes ne correspondent pas. (From index: %d; To index: %d)" + +#. Programmer's name for it: SCantEndSharedTransaction +#: Vcl/ib.pas:231 +msgid "Can't end a shared transaction unless it is forced and equal to the transaction's TimeoutAction" +msgstr "Ne peut terminer une transaction partagée à moins qu'elle soit forcée et égale au TimeoutAction de la transaction." + +#. Programmer's name for it: SFieldUnsupportedType +#: Vcl/ib.pas:232 +msgid "Unsupported Field Type" +msgstr "Type de champ non supporté" + +#. Programmer's name for it: SCircularDataLink +#: Vcl/ib.pas:233 +msgid "Circular DataLink Reference" +msgstr "Référence circulaire DataLink" + +#. Programmer's name for it: SEmptySQLStatement +#: Vcl/ib.pas:234 +msgid "Empty SQL Statement" +msgstr "Instruction SQL vide" + +#. Programmer's name for it: SIsASelectStatement +#: Vcl/ib.pas:235 +msgid "use Open for a Select Statement" +msgstr "Utilisez Open pour l'instruction Select" + +#. Programmer's name for it: SRequiredParamNotSet +#: Vcl/ib.pas:236 +msgid "Required Param value not set" +msgstr "Valeur de paramètre requise non définie" + +#. Programmer's name for it: SNoStoredProcName +#: Vcl/ib.pas:237 +msgid "No Stored Procedure Name assigned" +msgstr "Aucun nom de procédure stockée affecté" + +#. Programmer's name for it: SIsAExecuteProcedure +#: Vcl/ib.pas:238 +msgid "use ExecProc for Procedure; use TQuery for Select procedures" +msgstr "Utilisez ExecProc pour Procedure; Utilisez TQuery pour Select procedures" + +#. Programmer's name for it: SUpdateFailed +#: Vcl/ib.pas:239 +msgid "Update Failed" +msgstr "Echec de la mise à jour" + +#. Programmer's name for it: SNotCachedUpdates +#: Vcl/ib.pas:240 +msgid "CachedUpdates not enabled" +msgstr "CachedUpdates non activé" + +#. Programmer's name for it: SNotLiveRequest +#: Vcl/ib.pas:241 +msgid "Request is not live - cannot modify" +msgstr "La requête n'est pas vivante. Ne peut la modifier" + +#. Programmer's name for it: SNoProvider +#: Vcl/ib.pas:242 +msgid "No Provider" +msgstr "Aucun fournisseur" + +#. Programmer's name for it: SNoRecordsAffected +#: Vcl/ib.pas:243 +msgid "No Records Affected" +msgstr "Aucun enregistrement affecté" + +#. Programmer's name for it: SNoTableName +#: Vcl/ib.pas:244 +msgid "No Table Name assigned" +msgstr "Aucun nom de table affecté" + +#. Programmer's name for it: SCannotCreatePrimaryIndex +#: Vcl/ib.pas:245 +msgid "Cannot Create Primary Index; are created automatically" +msgstr "Ne peut créer l'index primaire ; créé automatiquement" + +#. Programmer's name for it: SCannotDropSystemIndex +#: Vcl/ib.pas:246 +msgid "Cannot Drop System Index" +msgstr "Ne peut abandonner l'index système" + +#. Programmer's name for it: STableNameMismatch +#: Vcl/ib.pas:247 +msgid "Table Name Mismatch" +msgstr "Nom de table inadéquat" + +#. Programmer's name for it: SIndexFieldMissing +#: Vcl/ib.pas:248 +msgid "Index Field Missing" +msgstr "Champ index manquant" + +#. Programmer's name for it: SInvalidCancellation +#: Vcl/ib.pas:249 +msgid "Cannot Cancel events while processing" +msgstr "Ne peut annuler les événements lors du traitement" + +#. Programmer's name for it: SInvalidEvent +#: Vcl/ib.pas:250 +msgid "Invalid Event" +msgstr "Evénement incorrect" + +#. Programmer's name for it: SMaximumEvents +#: Vcl/ib.pas:251 +msgid "Exceded Maximum Event limits" +msgstr "Limite maxi d'événements dépassée" + +#. Programmer's name for it: SNoEventsRegistered +#: Vcl/ib.pas:252 +msgid "No Events Registered" +msgstr "Aucun événement recensé" + +#. Programmer's name for it: SInvalidQueueing +#: Vcl/ib.pas:253 +msgid "Invalid Queueing" +msgstr "Queueing incorrect" + +#. Programmer's name for it: SInvalidRegistration +#: Vcl/ib.pas:254 +msgid "Invalid Registration" +msgstr "Enregistrement incorrect" + +#. Programmer's name for it: SInvalidBatchMove +#: Vcl/ib.pas:255 +msgid "Invalid Batch Move" +msgstr "Batch Move invalide" + +#. Programmer's name for it: SSQLDialectInvalid +#: Vcl/ib.pas:256 +msgid "SQL Dialect Invalid" +msgstr "Dialecte SQL incorrect" + +#. Programmer's name for it: SSPBConstantNotSupported +#: Vcl/ib.pas:257 +msgid "SPB Constant Not supported" +msgstr "Constante SPB non supportée" + +#. Programmer's name for it: SSPBConstantUnknown +#: Vcl/ib.pas:258 +msgid "SPB Constant Unknown" +msgstr "Constante SPB inconnue" + +#. Programmer's name for it: SServiceActive +#: Vcl/ib.pas:259 +msgid "Cannot perform operation -- service is not attached" +msgstr "Ne peut effectuer l'opération -- le service n'est pas attaché." + +#. Programmer's name for it: SServiceInActive +#: Vcl/ib.pas:260 +msgid "Cannot perform operation -- service is attached" +msgstr "Ne peut effectuer l'opération -- le service est attaché." + +#. Programmer's name for it: SServerNameMissing +#: Vcl/ib.pas:261 +msgid "Server Name Missing" +msgstr "Nom de serveur manquant" + +#. Programmer's name for it: SQueryParamsError +#: Vcl/ib.pas:262 +msgid "Query Parameters missing or incorrect" +msgstr "Paramètres de requête manquants ou incorrects" + +#. Programmer's name for it: SStartParamsError +#: Vcl/ib.pas:263 +msgid "start Parameters missing or incorrect" +msgstr "Paramètres start manquants ou incorrect" + +#. Programmer's name for it: SOutputParsingError +#: Vcl/ib.pas:264 +msgid "Unexpected Output buffer value" +msgstr "Valeur de tampon de sortie inattendue" + +#. Programmer's name for it: SUseSpecificProcedures +#: Vcl/ib.pas:265 +msgid "Generic ServiceStart not applicable: Use Specific Procedures to set configuration params" +msgstr "ServiceStart générique non applicable : Utilisez des procédures spécifiques pour définir les paramètres de configuration" + +#. Programmer's name for it: SSQLMonitorAlreadyPresent +#: Vcl/ib.pas:266 +msgid "SQL Monitor Instance is already present" +msgstr "Une instance du Moniteur SQL est déjà présente" + +#. Programmer's name for it: SEOFInComment +#: Vcl/ibsql.pas:24 +msgid "EOF in comment detected" +msgstr "EOF détecté dans un commentaire" + +#. Programmer's name for it: SEOFInString +#: Vcl/ibsql.pas:25 +msgid "EOF in string detected" +msgstr "EOF détecté dans une chaîne" + +#. Programmer's name for it: SParamNameExpected +#: Vcl/ibsql.pas:26 +msgid "Parameter name expected" +msgstr "Nom de paramètre attendu" + +#. Programmer's name for it: SCantPrintValue +#: Vcl/ibsqlmonitor.pas:24 +msgid "Cannot print value" +msgstr "Ne peut imprimer la valeur" + +#. Programmer's name for it: SEOFReached +#: Vcl/ibsqlmonitor.pas:25 +msgid "SEOFReached" +msgstr "SEOFReached" + +#. Programmer's name for it: SProviderNotExported +#: Vcl/midconst.pas:33 +msgid "Provider not exported: %s" +msgstr "Fournisseur non exporté : %s" + +#. Programmer's name for it: SNoDataProvider +#: Vcl/midconst.pas:36 +msgid "Missing data provider or data packet" +msgstr "Fournisseur de données ou paquet de données manquant" + +#. Programmer's name for it: SInvalidDataPacket +#: Vcl/midconst.pas:37 +msgid "Invalid data packet" +msgstr "Paquet de données incorrect" + +#. Programmer's name for it: SRefreshError +#: Vcl/midconst.pas:38 +msgid "Must apply updates before refreshing data" +msgstr "Vous devez valider les modifications avant de rafraîchir les données" + +#. Programmer's name for it: SProviderInvalid +#: Vcl/midconst.pas:39 +msgid "Invalid provider. Provider was freed by the application server" +msgstr "Fournisseur incorrect. Le fournisseur a été libéré par le serveur d'application" + +#. Programmer's name for it: SServerNameBlank +#: Vcl/midconst.pas:40 +msgid "Cannot connect, %s must contain a valid ServerName or ServerGUID" +msgstr "Impossible de se connecter, %s doit contenir un ServerName ou ServerGUID correct" + +#. Programmer's name for it: SRepositoryIdBlank +#: Vcl/midconst.pas:41 +msgid "Cannot connect, %s must contain a valid repository id" +msgstr "Connexion impossible, %s doit contenir un id de référentiel correct" + +#. Programmer's name for it: SAggsGroupingLevel +#: Vcl/midconst.pas:42 +msgid "Grouping level exceeds current index field count" +msgstr "Le niveau de groupement dépasse le nombre de champs d'index actuel" + +#. Programmer's name for it: SAggsNoSuchLevel +#: Vcl/midconst.pas:43 +msgid "Grouping level not defined" +msgstr "Niveau de groupement non défini" + +#. Programmer's name for it: SNoCircularReference +#: Vcl/midconst.pas:44 +msgid "Circular provider references not allowed" +msgstr "Références de fournisseurs circulaires non autorisées" + +#. Programmer's name for it: SErrorLoadingMidas +#: Vcl/midconst.pas:45 +msgid "Error loading MIDAS.DLL" +msgstr "Erreur au chargement de MIDAS.DLL" + +#. Programmer's name for it: SCannotCreateDataSet +#: Vcl/midconst.pas:46 +msgid "No fields defined. Cannot create dataset" +msgstr "Aucun champ défini. Ne peut créer le dataset" + +#. Programmer's name for it: SSocketReadError +#: Vcl/midconst.pas:49 +msgid "Error reading from socket" +msgstr "Erreur de lecture de la socket" + +#. Programmer's name for it: SInvalidProviderName +#: Vcl/midconst.pas:50 +msgid "Provider name \"%s\" was not recognized by the server" +msgstr "Le nom de fournisseur \"%s\" n'a pas été reconnu par le serveur" + +#. Programmer's name for it: SBadVariantType +#: Vcl/midconst.pas:51 +msgid "Unsupported variant type: %s" +msgstr "Type de variant non supporté : %s" + +#. Programmer's name for it: SInvalidAction +#: Vcl/midconst.pas:52 +msgid "Invalid action received: %d" +msgstr "Action reçue incorrecte : %d" + +#. Programmer's name for it: SInvalidResponse +#: Vcl/midconst.pas:55 +msgid "Invalid response" +msgstr "Réponse incorrecte" + +#. Programmer's name for it: STooManyRecordsModified +#: Vcl/midconst.pas:57 +msgid "Update affected more than 1 record." +msgstr "La mise à jour a affecté plus d'un enregistrement" + +#. Programmer's name for it: SInvalidOptParamType +#: Vcl/midconst.pas:60 +msgid "Value cannot be stored in an optional parameter" +msgstr "La valeur ne peut être stockée dans un paramètre optionnel" + +#. Programmer's name for it: SConstraintFailed +#: Vcl/midconst.pas:62 +msgid "Record or field constraint failed." +msgstr "La contrainte d'enregistrement ou de champ a échoué." + +#. Programmer's name for it: SField +#: Vcl/midconst.pas:63 +msgid "Field" +msgstr "Champ" + +#. Programmer's name for it: SReadOnlyProvider +#: Vcl/midconst.pas:64 +msgid "Cannot apply updates to a ReadOnly provider" +msgstr "Ne peut appliquer les mises à jour à un fournisseur en lecture seule" + +#. Programmer's name for it: SNoKeySpecified +#: Vcl/midconst.pas:65 +msgid "Unable to find record. No key specified" +msgstr "Ne peut trouver l'enregistrement. Aucune clé spécifiée" + +#. Programmer's name for it: SFieldNameTooLong +#: Vcl/midconst.pas:67 +msgid "Field name cannot be longer then %d characters. Try setting ObjectView to True on the dataset" +msgstr "Le nom de champ ne peut dépasser %d caractères. Essayez de définir ObjectView à True dans le dataset" + +#. Programmer's name for it: SNoDataSets +#: Vcl/midconst.pas:68 +msgid "Cannot resolve to dataset when using nested datasets or references" +msgstr "Ne peut résoudre vers un dataset lors de l'utilisation de datasets ou de références imbriqués" + +#. Programmer's name for it: SRecConstFail +#: Vcl/midconst.pas:69 +msgid "Preparation of record constraint failed with error \"%s\"" +msgstr "La préparation de contrainte d'enregistrement a échoué avec l'erreur %s" + +#. Programmer's name for it: SFieldConstFail +#: Vcl/midconst.pas:70 +msgid "Preparation of field constraint failed with error \"%s\"" +msgstr "La préparation de contrainte de champ a échoué avec l'erreur %s" + +#. Programmer's name for it: SDefExprFail +#: Vcl/midconst.pas:71 +msgid "Preparation of default expression failed with error \"%s\"" +msgstr "La préparation d'expression par défaut a échoué avec l'erreur %s" + +#. Programmer's name for it: SArrayElementError +#: Vcl/midconst.pas:72 +msgid "Array elements of type %s are not supported" +msgstr "Les éléments de tableau de type %s ne sont pas supportés" + +#. Programmer's name for it: SNoTableName +#: Vcl/midconst.pas:73 +msgid "Unable to resolve records. Table name not found." +msgstr "Ne peut résoudre les enregistrements. Nom de table non trouvé." + +#. Programmer's name for it: SNoEditsAllowed +#: Vcl/midconst.pas:74 +msgid "Modifications are not allowed" +msgstr "Modifications non autorisées" + +#. Programmer's name for it: SNoDeletesAllowed +#: Vcl/midconst.pas:75 +msgid "Deletes are not allowed" +msgstr "Suppressions non autorisées" + +#. Programmer's name for it: SNoInsertsAllowed +#: Vcl/midconst.pas:76 +msgid "Inserts are not allowed" +msgstr "Insertions non autorisées" + +#. Programmer's name for it: SCannotChangeCommandText +#: Vcl/midconst.pas:77 +msgid "CommandText changes are not allowed" +msgstr "Modifications CommandText non autorisées" + +#. Programmer's name for it: SNoServers +#: Vcl/midconst.pas:80 +msgid "No server available" +msgstr "Aucun serveur disponible" + +#. Programmer's name for it: SReturnError +#: Vcl/midconst.pas:83 +msgid "Expected return value not received" +msgstr "Valeur de retour attendue non reçue" + +#. Programmer's name for it: SNoWinSock2 +#: Vcl/midconst.pas:84 +msgid "WinSock 2 must be installed to use the socket connection" +msgstr "WinSock 2 doit être installé pour utiliser la connexion socket" + +#. Programmer's name for it: SURLRequired +#: Vcl/midconst.pas:87 +msgid "URL required" +msgstr "URL requis" + +#. Programmer's name for it: SDefaultURL +#: Vcl/midconst.pas:88 +msgid "http://server.company.com/scripts/httpsrvr.dll" +msgstr "http://server.company.com/scripts/httpsrvr.dll" + +#. Programmer's name for it: SInvalidURL +#: Vcl/midconst.pas:89 +msgid "URL must be in the form \"http://server.company.com/scripts/httpsrvr.dll\"" +msgstr "L'URL doit être de la forme \"http://server.company.com/scripts/httpsrvr.dll\"" + +#. Programmer's name for it: SServerIsBusy +#: Vcl/midconst.pas:90 +msgid "Server is busy" +msgstr "Le serveur est occupé" + +#. Programmer's name for it: SObjectNotAvailable +#: Vcl/midconst.pas:92 +msgid "Object not available: %s" +msgstr "Objet non disponible : %s" + +#. Programmer's name for it: SBadPropValue +#: Vcl/oleconst.pas:15 +msgid "'%s' is not a valid property value" +msgstr "'%s' n'est pas une valeur de propriété correcte" + +#. Programmer's name for it: SCannotActivate +#: Vcl/oleconst.pas:16 +msgid "OLE control activation failed" +msgstr "Echec de l'activation du contrôle OLE" + +#. Programmer's name for it: SNoWindowHandle +#: Vcl/oleconst.pas:17 +msgid "Could not obtain OLE control window handle" +msgstr "Impossible d'obtenir le handle de fenêtre du contrôle OLE" + +#. Programmer's name for it: SOleError +#: Vcl/oleconst.pas:18 +msgid "OLE error %.8x" +msgstr "Erreur OLE %.8x" + +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:19 +msgid "Variant does not reference an OLE object" +msgstr "Le variant ne référence pas un objet OLE" + +#. Programmer's name for it: SVarNotAutoObject +#. Programmer's name for it: SVarNotObject +#: Vcl/oleconst.pas:20 +msgid "Variant does not reference an automation object" +msgstr "Le variant ne référence pas un objet Automation" + +#. Programmer's name for it: SNoMethod +#: Vcl/oleconst.pas:21 +msgid "Method '%s' not supported by OLE object" +msgstr "Méthode '%s' non supportée par l'objet OLE" + +#. Programmer's name for it: SLinkProperties +#: Vcl/oleconst.pas:22 +msgid "Link Properties" +msgstr "Propriétés de liaison" + +#. Programmer's name for it: SInvalidLinkSource +#: Vcl/oleconst.pas:23 +msgid "Cannot link to an invalid source." +msgstr "Impossible de lier à une source incorrecte." + +#. Programmer's name for it: SCannotBreakLink +#: Vcl/oleconst.pas:24 +msgid "Break link operation is not supported." +msgstr "Opération interruption de liaison non supportée." + +#. Programmer's name for it: SLinkedObject +#: Vcl/oleconst.pas:25 +msgid "Linked %s" +msgstr "%s lié(e)" + +#. Programmer's name for it: SEmptyContainer +#: Vcl/oleconst.pas:26 +msgid "Operation not allowed on an empty OLE container" +msgstr "Opération non autorisée pour un conteneur OLE vide" + +#. Programmer's name for it: SInvalidVerb +#: Vcl/oleconst.pas:27 +msgid "Invalid object verb" +msgstr "Verbe d'objet incorrect" + +#. Programmer's name for it: SPropDlgCaption +#: Vcl/oleconst.pas:28 +msgid "%s Properties" +msgstr "Propriétés %s" + +#. Programmer's name for it: SInvalidLicense +#: Vcl/oleconst.pas:30 +msgid "License information for %s is invalid" +msgstr "Les informations de licence pour %s sont incorrectes" + +#. Programmer's name for it: SNotLicensed +#: Vcl/oleconst.pas:31 +msgid "License information for %s not found. You cannot use this control in design mode" +msgstr "Informations de licence pour %s non trouvées. Vous ne pouvez utiliser ce contrôle en mode conception" + +#. Programmer's name for it: sNoRunningObject +#: Vcl/oleconst.pas:32 +msgid "Unable to retrieve a pointer to a running object registered with OLE for %s/%s" +msgstr "Ne peut récupérer un pointeur sur un objet en cours d'exécution recensé avec OLE pour %s/%s" + +#. Programmer's name for it: SServiceOnly +#: Vcl/scktcnst.pas:29 +msgid "The Socket Server can only be run as a service on NT 3.51 and prior" +msgstr "Le serveur de Socket ne fonctionne en mode service que sur système NT 3.51 ou plus ancien." + +#. Programmer's name for it: SErrClose +#: Vcl/scktcnst.pas:30 +msgid "Cannot exit when there are active connections. Kill connections?" +msgstr "Arrêt impossible tant que des connexions sont établies. Stopper les connexions?" + +#. Programmer's name for it: SErrChangeSettings +#: Vcl/scktcnst.pas:31 +msgid "Cannot change settings when there are active connections. Kill connections?" +msgstr "Impossible de changer les paramètres tant que des connexions sont établies. Stopper les connexions?" + +#. Programmer's name for it: SQueryDisconnect +#: Vcl/scktcnst.pas:32 +msgid "Disconnecting clients can cause application errors. Continue?" +msgstr "Déconnecter un client peut provoquer des erreurs dans le programme. Voulez-vous continuer?" + +#. Programmer's name for it: SOpenError +#: Vcl/scktcnst.pas:33 +msgid "Error opening port %d with error: %s" +msgstr "Erreur à l'ouverture du port %d: %s" + +#. Programmer's name for it: SNotShown +#: Vcl/scktcnst.pas:35 +msgid "(Not Shown)" +msgstr "(invisible)" + +#. Programmer's name for it: SStatusline +#: Vcl/scktcnst.pas:37 +msgid "%d current connections" +msgstr "%d connexions actuellement" + +#. Programmer's name for it: SAlreadyRunning +#: Vcl/scktcnst.pas:38 +msgid "The Socket Server is already running" +msgstr "Le serveur de socket est déjà en fonction" + +#. Programmer's name for it: SNotUntilRestart +#: Vcl/scktcnst.pas:39 +msgid "This change will not take affect until the Socket Server is restarted" +msgstr "Ce changement ne serra effectif qu'après le redémarrage du serveur de Socket" + +#. Programmer's name for it: sInvalidActionRegistration +#: Vcl/webconst.pas:15 +msgid "Invalid Action registration" +msgstr "Enregistrement d'action incorrect" + +#. Programmer's name for it: sDuplicateActionName +#: Vcl/webconst.pas:16 +msgid "Duplicate action name" +msgstr "Nom d'action dupliqué" + +#. Programmer's name for it: sOnlyOneDispatcher +#: Vcl/webconst.pas:17 +msgid "Only one WebDispatcher per form/data module" +msgstr "Un seul WebDispatcher par fiche/module de données" + +#. Programmer's name for it: sHTTPItemName +#: Vcl/webconst.pas:18 +msgid "Name" +msgstr "Nom" + +#. Programmer's name for it: sHTTPItemURI +#: Vcl/webconst.pas:19 +msgid "PathInfo" +msgstr "Chemin" + +#. Programmer's name for it: sHTTPItemEnabled +#: Vcl/webconst.pas:20 +msgid "Enabled" +msgstr "Activé" + +#. Programmer's name for it: sHTTPItemProducer +#: Vcl/webconst.pas:22 +msgid "Producer" +msgstr "Producteur" + +#. Programmer's name for it: sTooManyColumns +#: Vcl/webconst.pas:26 +msgid "Too many table columns" +msgstr "Trop de colonnes de table" + +#. Programmer's name for it: sFieldNameColumn +#: Vcl/webconst.pas:27 +msgid "Field Name" +msgstr "Nom champ" + +#. Programmer's name for it: sFieldTypeColumn +#: Vcl/webconst.pas:28 +msgid "Field Type" +msgstr "Type champ" + +#. Programmer's name for it: SCorbaDllNotLoaded +#: Rtl/Corba/corbcnst.pas:15 +msgid "Unable to load CORBA libraries" +msgstr "Ne peut charger les bibliothèques CORBA" + +#. Programmer's name for it: SCorbaNotInitialized +#: Rtl/Corba/corbcnst.pas:16 +msgid "CORBA libraries are unavailable or not initialized" +msgstr "Les bibliothèques CORBA sont indisponibles ou non initialisées" + +#. Programmer's name for it: SCorbaSkeletonNotRegistered +#: Rtl/Corba/corbcnst.pas:17 +msgid "CORBA server skeleton not registered for object %s" +msgstr "Squelette de serveur CORBA non recensé pour l'objet %s" + +#. Programmer's name for it: SCorbaStubNotRegistered +#: Rtl/Corba/corbcnst.pas:18 +msgid "CORBA client stub not registered" +msgstr "Stub client CORBA non recensé" + +#. Programmer's name for it: SCorbaInterfaceIDNotRegister +#: Rtl/Corba/corbcnst.pas:19 +msgid "CORBA interface not registered" +msgstr "Interface CORBA non recensée" + +#. Programmer's name for it: SCorbaRepositoryIDNotRegistered +#: Rtl/Corba/corbcnst.pas:20 +msgid "CORBA Repository ID \"%s\" not registered" +msgstr "Id de référentiel CORBA \"%s\" non recensé" + +#. Programmer's name for it: SCorbaIncompleteFactory +#: Rtl/Corba/corbcnst.pas:21 +msgid "CORBA Factory did not implement CreateInterface" +msgstr "La fabrique CORBA n'a pas implémenté CreateInterface" + +#. Programmer's name for it: sInvalidTypeCast +#: Rtl/Corba/corbcnst.pas:24 +msgid "Variant cannot be converted to a CORBA Any" +msgstr "Le variant ne peut être converti en Any CORBA" + +#. Programmer's name for it: sNotCorbaObject +#: Rtl/Corba/corbcnst.pas:25 +msgid "Variant/Any not a CORBA object" +msgstr "Le Variant/Any n'est pas un objet CORBA" + +#. Programmer's name for it: sParamTypeCast +#: Rtl/Corba/corbcnst.pas:26 +msgid "Parameter (%d) of method %s not of the correct type" +msgstr "Le paramètre (%d) de la méthode %s n'est pas du type correct" + +#. Programmer's name for it: sParamOut +#: Rtl/Corba/corbcnst.pas:27 +msgid "Parameter (%d) of method %s is an out or in/out parameter and requires a variable reference" +msgstr "Le paramètre (%d) de la méthode %s est un paramètre sortie ou entrée/sortie et requiert une référence de variable" + +#. Programmer's name for it: sNoRepository +#: Rtl/Corba/corbcnst.pas:28 +msgid "Could not perform CORBA Dispatch, no interface repository found" +msgstr "Ne peut effectuer le Dispatch CORBA, aucun référentiel d'interface trouvé" + +#. Programmer's name for it: sInvalidParameterCount +#: Rtl/Corba/corbcnst.pas:29 +msgid "Incorrect number of parameters to method %s" +msgstr "Nombre de paramètres incorrect pour la méthode %s" + +#. Programmer's name for it: sMethodNotFound +#: Rtl/Corba/corbcnst.pas:30 +msgid "Method %s not found" +msgstr "Méthode %s non trouvée" + +#. Programmer's name for it: sConnecting +#: Rtl/Corba/corbcnst.pas:31 +msgid "Connecting to CORBA server..." +msgstr "Connexion au serveur CORBA..." + +#. Programmer's name for it: SCreateRegKeyError +#: Rtl/Sys/comconst.pas:15 +msgid "Error creating system registry entry" +msgstr "Erreur à la création de l'entrée de registre système" + +#. Programmer's name for it: SObjectFactoryMissing +#: Rtl/Sys/comconst.pas:17 +msgid "Object factory for class %s missing" +msgstr "Object factory manquant pour la classe %s" + +#. Programmer's name for it: STypeInfoMissing +#: Rtl/Sys/comconst.pas:18 +msgid "Type information missing for class %s" +msgstr "Information de type manquante pour la classe %s" + +#. Programmer's name for it: SBadTypeInfo +#: Rtl/Sys/comconst.pas:19 +msgid "Incorrect type information for class %s" +msgstr "Information de type incorrecte pour la classe %s" + +#. Programmer's name for it: SDispIntfMissing +#: Rtl/Sys/comconst.pas:20 +msgid "Dispatch interface missing from class %s" +msgstr "Interface dispatch manquante dans la classe %s" + +#. Programmer's name for it: SNoMethod +#: Rtl/Sys/comconst.pas:21 +msgid "Method '%s' not supported by automation object" +msgstr "Méthode '%s' non supportée par l'objet Automation" + +#. Programmer's name for it: SDCOMNotInstalled +#: Rtl/Sys/comconst.pas:23 +msgid "DCOM not installed" +msgstr "DCOM non installé" + +#. Programmer's name for it: SDAXError +#: Rtl/Sys/comconst.pas:24 +msgid "DAX Error" +msgstr "Erreur DAX" + +#. Programmer's name for it: SAutomationWarning +#: Rtl/Sys/comconst.pas:26 +msgid "COM Server Warning" +msgstr "Avertissement du serveur COM" + +#. Programmer's name for it: SNoCloseActiveServer1 +#: Rtl/Sys/comconst.pas:29 +msgid "There are still active COM objects in this application. One or more clients may have references to these objects, so manually closing " +msgstr "Il y a encore des serveurs COM actifs dans cette application. Un ou plusieurs clients ont peut-être des références à ces objets, donc la fermeture manuelle de " + +#. Programmer's name for it: SNoCloseActiveServer2 +#: Rtl/Sys/comconst.pas:32 +msgid "" +"this application may cause those client application(s) to fail.\n" +"\n" +"Are you sure you want to close this application?" +msgstr "" +"cette application peut provoquer des erreurs dans les clients.\n" +"\n" +"Etes-vous sûr de vouloir fermer cette application ?" + +#. Programmer's name for it: SUnknown +#: Rtl/Sys/sysconst.pas:15 +msgid "" +msgstr "" + +#. Programmer's name for it: SInvalidInteger +#: Rtl/Sys/sysconst.pas:16 +msgid "'%s' is not a valid integer value" +msgstr "'%s' n'est pas une valeur entière correcte" + +#. Programmer's name for it: SInvalidFloat +#: Rtl/Sys/sysconst.pas:17 +msgid "'%s' is not a valid floating point value" +msgstr "'%s' n'est pas une valeur en virgule flottante correcte" + +#. Programmer's name for it: SInvalidDate +#: Rtl/Sys/sysconst.pas:18 +msgid "'%s' is not a valid date" +msgstr "'%s' n'est pas une date correcte" + +#. Programmer's name for it: SInvalidTime +#: Rtl/Sys/sysconst.pas:19 +msgid "'%s' is not a valid time" +msgstr "'%s' n'est pas une heure correcte" + +#. Programmer's name for it: SInvalidDateTime +#: Rtl/Sys/sysconst.pas:20 +msgid "'%s' is not a valid date and time" +msgstr "'%s' n'est pas une date et heure correcte" + +#. Programmer's name for it: SOutOfMemory +#: Rtl/Sys/sysconst.pas:23 +msgid "Out of memory" +msgstr "Mémoire insuffisante" + +#. Programmer's name for it: SInOutError +#: Rtl/Sys/sysconst.pas:24 +msgid "I/O error %d" +msgstr "Erreur E/S %d" + +#. Programmer's name for it: SFileNotFound +#: Rtl/Sys/sysconst.pas:25 +msgid "File not found" +msgstr "Fichier introuvable" + +#. Programmer's name for it: SInvalidFilename +#: Rtl/Sys/sysconst.pas:26 +msgid "Invalid filename" +msgstr "Nom de fichier incorrect" + +#. Programmer's name for it: STooManyOpenFiles +#: Rtl/Sys/sysconst.pas:27 +msgid "Too many open files" +msgstr "Trop de fichiers ouverts" + +#. Programmer's name for it: SAccessDenied +#: Rtl/Sys/sysconst.pas:28 +msgid "File access denied" +msgstr "Accès au fichier refusé" + +#. Programmer's name for it: SEndOfFile +#: Rtl/Sys/sysconst.pas:29 +msgid "Read beyond end of file" +msgstr "Lecture au-delà de la fin de fichier" + +#. Programmer's name for it: SDiskFull +#: Rtl/Sys/sysconst.pas:30 +msgid "Disk full" +msgstr "Disque plein" + +#. Programmer's name for it: SInvalidInput +#: Rtl/Sys/sysconst.pas:31 +msgid "Invalid numeric input" +msgstr "Saisie numérique incorrecte" + +#. Programmer's name for it: SDivByZero +#: Rtl/Sys/sysconst.pas:32 +msgid "Division by zero" +msgstr "Division par zéro" + +#. Programmer's name for it: SRangeError +#: Rtl/Sys/sysconst.pas:33 +msgid "Range check error" +msgstr "Erreur de vérification d'étendue" + +#. Programmer's name for it: SIntOverflow +#: Rtl/Sys/sysconst.pas:34 +msgid "Integer overflow" +msgstr "Débordement d'entier" + +#. Programmer's name for it: SInvalidOp +#: Rtl/Sys/sysconst.pas:35 +msgid "Invalid floating point operation" +msgstr "Opération en virgule flottante incorrecte" + +#. Programmer's name for it: SZeroDivide +#: Rtl/Sys/sysconst.pas:36 +msgid "Floating point division by zero" +msgstr "Division par zéro en virgule flottante" + +#. Programmer's name for it: SOverflow +#: Rtl/Sys/sysconst.pas:37 +msgid "Floating point overflow" +msgstr "Débordement en virgule flottante" + +#. Programmer's name for it: SUnderflow +#: Rtl/Sys/sysconst.pas:38 +msgid "Floating point underflow" +msgstr "Débordement inférieur flottant" + +#. Programmer's name for it: SInvalidPointer +#: Rtl/Sys/sysconst.pas:39 +msgid "Invalid pointer operation" +msgstr "Opération de pointeur incorrecte" + +#. Programmer's name for it: SInvalidCast +#: Rtl/Sys/sysconst.pas:40 +msgid "Invalid class typecast" +msgstr "Transtypage de classe incorrect" + +#. Programmer's name for it: SAccessViolation +#: Rtl/Sys/sysconst.pas:41 +msgid "Access violation at address %p. %s of address %p" +msgstr "Violation d'accès à l'adresse %p. %s de l'adresse %p" + +#. Programmer's name for it: SStackOverflow +#: Rtl/Sys/sysconst.pas:42 +msgid "Stack overflow" +msgstr "Débordement de pile" + +#. Programmer's name for it: SControlC +#: Rtl/Sys/sysconst.pas:43 +msgid "Control-C hit" +msgstr "Frappe de Contrôle-C" + +#. Programmer's name for it: SPrivilege +#: Rtl/Sys/sysconst.pas:44 +msgid "Privileged instruction" +msgstr "Instruction privilégiée" + +#. Programmer's name for it: SOperationAborted +#: Rtl/Sys/sysconst.pas:45 +msgid "Operation aborted" +msgstr "Opération abandonnée" + +#. Programmer's name for it: SException +#: Rtl/Sys/sysconst.pas:46 +msgid "" +"Exception %s in module %s at %p.\n" +"%s%s" +msgstr "" +"Exception %s dans le module %s à %p.\n" +"%s%s" + +#. Programmer's name for it: SExceptTitle +#: Rtl/Sys/sysconst.pas:47 +msgid "Application Error" +msgstr "Erreur d'application" + +#. Programmer's name for it: SInvalidFormat +#: Rtl/Sys/sysconst.pas:48 +msgid "Format '%s' invalid or incompatible with argument" +msgstr "Le format '%s' est incorrect ou incompatible avec l'argument" + +#. Programmer's name for it: SArgumentMissing +#: Rtl/Sys/sysconst.pas:49 +msgid "No argument for format '%s'" +msgstr "Aucun argument pour le format '%s'" + +#. Programmer's name for it: SInvalidVarCast +#: Rtl/Sys/sysconst.pas:50 +msgid "Invalid variant type conversion" +msgstr "Conversion de type variant incorrecte" + +#. Programmer's name for it: SInvalidVarOp +#: Rtl/Sys/sysconst.pas:51 +msgid "Invalid variant operation" +msgstr "Opération de variant incorrecte" + +#. Programmer's name for it: SDispatchError +#: Rtl/Sys/sysconst.pas:52 +msgid "Variant method calls not supported" +msgstr "Appels de méthode variante non supportés" + +#. Programmer's name for it: SResultTooLong +#: Rtl/Sys/sysconst.pas:55 +msgid "Format result longer than 4096 characters" +msgstr "Résultat de format supérieur à 4096 caractères" + +#. Programmer's name for it: SFormatTooLong +#: Rtl/Sys/sysconst.pas:56 +msgid "Format string too long" +msgstr "Chaîne de format trop longue" + +#. Programmer's name for it: SVarArrayCreate +#: Rtl/Sys/sysconst.pas:57 +msgid "Error creating variant array" +msgstr "Erreur lors de la création de tableau de variants" + +#. Programmer's name for it: SVarNotArray +#: Rtl/Sys/sysconst.pas:58 +msgid "Variant is not an array" +msgstr "Le variant n'est pas un tableau" + +#. Programmer's name for it: SVarArrayBounds +#: Rtl/Sys/sysconst.pas:59 +msgid "Variant array index out of bounds" +msgstr "Indice de tableau de variants hors limites" + +#. Programmer's name for it: SExternalException +#: Rtl/Sys/sysconst.pas:60 +msgid "External exception %x" +msgstr "Exception externe %x" + +#. Programmer's name for it: SAssertionFailed +#: Rtl/Sys/sysconst.pas:61 +msgid "Assertion failed" +msgstr "Echec de l'assertion" + +#. Programmer's name for it: SIntfCastError +#: Rtl/Sys/sysconst.pas:62 +msgid "Interface not supported" +msgstr "Interface non supportée" + +#. Programmer's name for it: SSafecallException +#: Rtl/Sys/sysconst.pas:63 +msgid "Exception in safecall method" +msgstr "Exception dans méthode safecall" + +#. Programmer's name for it: SAssertError +#: Rtl/Sys/sysconst.pas:64 +msgid "%s (%s, line %d)" +msgstr "%s (%s, ligne %d)" + +#. Programmer's name for it: SAbstractError +#: Rtl/Sys/sysconst.pas:65 +msgid "Abstract Error" +msgstr "Erreur abstraite" + +#. Programmer's name for it: SModuleAccessViolation +#: Rtl/Sys/sysconst.pas:66 +msgid "Access violation at address %p in module '%s'. %s of address %p" +msgstr "Violation d'accès à l'adresse %p dans le module '%s'. %s de l'adresse %p" + +#. Programmer's name for it: SCannotReadPackageInfo +#: Rtl/Sys/sysconst.pas:67 +msgid "Cannot access package information for package '%s'" +msgstr "Impossible d'accéder à l'information de paquet pour le paquet '%s'" + +#. Programmer's name for it: sErrorLoadingPackage +#: Rtl/Sys/sysconst.pas:68 +msgid "" +"Can't load package %s.\n" +"%s" +msgstr "" +"Ne peut charger le paquet %s.\n" +"%s" + +#. Programmer's name for it: SInvalidPackageFile +#: Rtl/Sys/sysconst.pas:69 +msgid "Invalid package file '%s'" +msgstr "Fichier paquet incorrect '%s'" + +#. Programmer's name for it: SInvalidPackageHandle +#: Rtl/Sys/sysconst.pas:70 +msgid "Invalid package handle" +msgstr "Handle de paquet incorrect" + +#. Programmer's name for it: SDuplicatePackageUnit +#: Rtl/Sys/sysconst.pas:72 +msgid "Cannot load package '%s.' It contains unit '%s,';which is also contained in package '%s'" +msgstr "Ne peut charger le paquet '%s.' Il contient l'unité '%s', qui est également contenue dans le paquet '%s'" + +#. Programmer's name for it: SWin32Error +#: Rtl/Sys/sysconst.pas:73 +msgid "" +"Win32 Error. Code: %d.\n" +"%s" +msgstr "" +"Erreur Win32. Code : %d.\n" +"%s" + +#. Programmer's name for it: SUnkWin32Error +#: Rtl/Sys/sysconst.pas:74 +msgid "A Win32 API function failed" +msgstr "Une fonction de l'API Win32 a échoué" + +#. Programmer's name for it: SNL +#: Rtl/Sys/sysconst.pas:75 +msgid "Application is not licensed to use this feature" +msgstr "L'application n'a pas de licence pour cette fonctionnalité" + +#. Programmer's name for it: SShortMonthNameJan +#: Rtl/Sys/sysconst.pas:77 +msgid "Jan" +msgstr "Jan" + +#. Programmer's name for it: SShortMonthNameFeb +#: Rtl/Sys/sysconst.pas:78 +msgid "Feb" +msgstr "Fév" + +#. Programmer's name for it: SShortMonthNameMar +#: Rtl/Sys/sysconst.pas:79 +msgid "Mar" +msgstr "Mar" + +#. Programmer's name for it: SShortMonthNameApr +#: Rtl/Sys/sysconst.pas:80 +msgid "Apr" +msgstr "Avr" + +#. Programmer's name for it: SShortMonthNameMay +#. Programmer's name for it: SLongMonthNameMay +#: Rtl/Sys/sysconst.pas:81 +msgid "May" +msgstr "Mai" + +#. Programmer's name for it: SShortMonthNameJun +#: Rtl/Sys/sysconst.pas:82 +msgid "Jun" +msgstr "Jun" + +#. Programmer's name for it: SShortMonthNameJul +#: Rtl/Sys/sysconst.pas:83 +msgid "Jul" +msgstr "Jul" + +#. Programmer's name for it: SShortMonthNameAug +#: Rtl/Sys/sysconst.pas:84 +msgid "Aug" +msgstr "Aoû" + +#. Programmer's name for it: SShortMonthNameSep +#: Rtl/Sys/sysconst.pas:85 +msgid "Sep" +msgstr "Sep" + +#. Programmer's name for it: SShortMonthNameOct +#: Rtl/Sys/sysconst.pas:86 +msgid "Oct" +msgstr "Oct" + +#. Programmer's name for it: SShortMonthNameNov +#: Rtl/Sys/sysconst.pas:87 +msgid "Nov" +msgstr "Nov" + +#. Programmer's name for it: SShortMonthNameDec +#: Rtl/Sys/sysconst.pas:88 +msgid "Dec" +msgstr "Déc" + +#. Programmer's name for it: SLongMonthNameJan +#: Rtl/Sys/sysconst.pas:90 +msgid "January" +msgstr "Janvier" + +#. Programmer's name for it: SLongMonthNameFeb +#: Rtl/Sys/sysconst.pas:91 +msgid "February" +msgstr "Février" + +#. Programmer's name for it: SLongMonthNameMar +#: Rtl/Sys/sysconst.pas:92 +msgid "March" +msgstr "Mars" + +#. Programmer's name for it: SLongMonthNameApr +#: Rtl/Sys/sysconst.pas:93 +msgid "April" +msgstr "Avril" + +#. Programmer's name for it: SLongMonthNameJun +#: Rtl/Sys/sysconst.pas:95 +msgid "June" +msgstr "Juin" + +#. Programmer's name for it: SLongMonthNameJul +#: Rtl/Sys/sysconst.pas:96 +msgid "July" +msgstr "Juillet" + +#. Programmer's name for it: SLongMonthNameAug +#: Rtl/Sys/sysconst.pas:97 +msgid "August" +msgstr "Août" + +#. Programmer's name for it: SLongMonthNameSep +#: Rtl/Sys/sysconst.pas:98 +msgid "September" +msgstr "Septembre" + +#. Programmer's name for it: SLongMonthNameOct +#: Rtl/Sys/sysconst.pas:99 +msgid "October" +msgstr "Octobre" + +#. Programmer's name for it: SLongMonthNameNov +#: Rtl/Sys/sysconst.pas:100 +msgid "November" +msgstr "Novembre" + +#. Programmer's name for it: SLongMonthNameDec +#: Rtl/Sys/sysconst.pas:101 +msgid "December" +msgstr "Décembre" + +#. Programmer's name for it: SShortDayNameSun +#: Rtl/Sys/sysconst.pas:103 +msgid "Sun" +msgstr "Dim" + +#. Programmer's name for it: SShortDayNameMon +#: Rtl/Sys/sysconst.pas:104 +msgid "Mon" +msgstr "Lun" + +#. Programmer's name for it: SShortDayNameTue +#: Rtl/Sys/sysconst.pas:105 +msgid "Tue" +msgstr "Mar" + +#. Programmer's name for it: SShortDayNameWed +#: Rtl/Sys/sysconst.pas:106 +msgid "Wed" +msgstr "Mer" + +#. Programmer's name for it: SShortDayNameThu +#: Rtl/Sys/sysconst.pas:107 +msgid "Thu" +msgstr "Jeu" + +#. Programmer's name for it: SShortDayNameFri +#: Rtl/Sys/sysconst.pas:108 +msgid "Fri" +msgstr "Ven" + +#. Programmer's name for it: SShortDayNameSat +#: Rtl/Sys/sysconst.pas:109 +msgid "Sat" +msgstr "Sam" + +#. Programmer's name for it: SLongDayNameSun +#: Rtl/Sys/sysconst.pas:111 +msgid "Sunday" +msgstr "Dimanche" + +#. Programmer's name for it: SLongDayNameMon +#: Rtl/Sys/sysconst.pas:112 +msgid "Monday" +msgstr "Lundi" + +#. Programmer's name for it: SLongDayNameTue +#: Rtl/Sys/sysconst.pas:113 +msgid "Tuesday" +msgstr "Mardi" + +#. Programmer's name for it: SLongDayNameWed +#: Rtl/Sys/sysconst.pas:114 +msgid "Wednesday" +msgstr "Mercredi" + +#. Programmer's name for it: SLongDayNameThu +#: Rtl/Sys/sysconst.pas:115 +msgid "Thursday" +msgstr "Jeudi" + +#. Programmer's name for it: SLongDayNameFri +#: Rtl/Sys/sysconst.pas:116 +msgid "Friday" +msgstr "Vendredi" + +#. Programmer's name for it: SLongDayNameSat +#: Rtl/Sys/sysconst.pas:117 +msgid "Saturday" +msgstr "Samedi" + +#. Programmer's name: FONT 8 +#: Vcl/extdlgs.rc:14 +msgid "MS Sans Serif" +msgstr "MS Sans Serif" + +#. DSSCubeEditor..Caption +#: Decision Cube/mxdcube.dfm:6 +msgid "Decision Cube Editor" +msgstr "Editeur de cube de décision" + +#. DSSCubeEditor..Pager..DimensionInfo..Caption +#: Decision Cube/mxdcube.dfm:24 +msgid "Dimension Settings" +msgstr "Paramètres de dimensions" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionLabel..Caption +#: Decision Cube/mxdcube.dfm:31 +msgid "Display &Name" +msgstr "&Nom affiché :" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveLabel..Caption +#: Decision Cube/mxdcube.dfm:40 +msgid "&Active Type" +msgstr "Typ&e actif :" + +#. DSSCubeEditor..Pager..DimensionInfo..BinLabel..Caption +#: Decision Cube/mxdcube.dfm:49 +msgid "&Grouping" +msgstr "&Groupement :" + +#. DSSCubeEditor..Pager..DimensionInfo..StartLabel..Caption +#: Decision Cube/mxdcube.dfm:58 +msgid "&Initial Value" +msgstr "&Valeur initiale :" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeLabel..Caption +#: Decision Cube/mxdcube.dfm:67 +msgid "&Type" +msgstr "&Type :" + +#. DSSCubeEditor..Pager..DimensionInfo..Label1..Caption +#: Decision Cube/mxdcube.dfm:76 +msgid "Available &Fields" +msgstr "Champs &disponibles" + +#. DSSCubeEditor..Pager..DimensionInfo..Label2..Caption +#: Decision Cube/mxdcube.dfm:85 +msgid "For&mat" +msgstr "&Format :" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameLabel..Caption +#: Decision Cube/mxdcube.dfm:102 +msgid "&Base Field" +msgstr "&Champ de base :" + +#. DSSCubeEditor..Pager..DimensionInfo..CaptionEdit..Text +#: Decision Cube/mxdcube.dfm:122 +msgid "CaptionEdit" +msgstr "CaptionEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Hint +#: Decision Cube/mxdcube.dfm:130 +msgid "Control of when the information for this field is loaded" +msgstr "Contrôle quand l'information pour ce champ est chargée" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:136 +msgid "" +"Active\n" +"As Needed\n" +"Inactive\n" +msgstr "" +"actif\n" +"au besoin\n" +"inactif\n" + +#. DSSCubeEditor..Pager..DimensionInfo..ActiveEdit..Text +#: Decision Cube/mxdcube.dfm:139 +msgid "ActiveEdit" +msgstr "ActiveEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Hint +#: Decision Cube/mxdcube.dfm:147 +msgid "Group values for this field into ranges" +msgstr "Grouper les valeurs de champ en étendues" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:155 +msgid "" +"None\n" +"Year\n" +"Quarter\n" +"Month\n" +"Single Value\n" +msgstr "" +"Aucun\n" +"Année\n" +"Trimestre\n" +"Mois\n" +"Valeur simple\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BinEdit..Text +#: Decision Cube/mxdcube.dfm:158 +msgid "BinEdit" +msgstr "BinEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit....Items.Strings +#: Decision Cube/mxdcube.dfm:176 +msgid "" +"Dimension\n" +"Sum\n" +"Count\n" +"Average\n" +"Min\n" +"Max\n" +"GenericAgg\n" +"Unknown\n" +msgstr "" +"Dimension\n" +"Somme\n" +"Décompte\n" +"Moyenne\n" +"Minimum\n" +"Maximum\n" +"GenericAgg\n" +"Inconnu\n" + +#. DSSCubeEditor..Pager..DimensionInfo..TypeEdit..Text +#: Decision Cube/mxdcube.dfm:179 +msgid "TypeEdit" +msgstr "TypeEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..FormatEdit..Text +#: Decision Cube/mxdcube.dfm:190 +msgid "FormatEdit" +msgstr "FormatEdit" + +#. DSSCubeEditor..Pager..DimensionInfo..StartEdit....Height +#: Decision Cube/mxdcube.dfm:201 +msgid "Starting value for date ranges, Intial value for single valued dimensions\n" +msgstr "Valeur basse pour un intervalle de temps, valeur initiale pour une donnée unidimensionnelle\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit....Height +#: Decision Cube/mxdcube.dfm:214 +msgid "Fieldname (for a summary, the original field used to calculate the summary)\n" +msgstr "Nom du champ (pour les calculs de somme, champ de base à utiliser)\n" + +#. DSSCubeEditor..Pager..DimensionInfo..BaseNameEdit..Text +#: Decision Cube/mxdcube.dfm:217 +msgid "BaseNameEdit" +msgstr "BaseNameEdit" + +#. DSSCubeEditor..Pager..MemoryControl..Caption +#: Decision Cube/mxdcube.dfm:223 +msgid "Memory Control" +msgstr "Contrôle de la mémoire" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Hint +#: Decision Cube/mxdcube.dfm:229 +msgid "Control whether to load the decision cube at design time" +msgstr "Contrôle si le cube de décision est chargé à la conception" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..Caption +#: Decision Cube/mxdcube.dfm:230 +msgid "Designer Data Options" +msgstr "Options de données du concepteur" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioMetaData..Caption +#: Decision Cube/mxdcube.dfm:239 +msgid "Display Dimension &Names" +msgstr "Afficher les &noms de dimensions" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioDimensionData..Caption +#: Decision Cube/mxdcube.dfm:250 +msgid "Display Names and &Values" +msgstr "Afficher les noms et les &valeurs" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioAllData..Caption +#: Decision Cube/mxdcube.dfm:259 +msgid "Display Names, Values, and &Totals" +msgstr "Afficher les noms, valeurs et &totaux" + +#. DSSCubeEditor..Pager..MemoryControl..Panel1..RadioNoData..Caption +#: Decision Cube/mxdcube.dfm:268 +msgid "&Run Time Display Only" +msgstr "Affichage à l'e&xécution seulement" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Caption +#: Decision Cube/mxdcube.dfm:278 +msgid "Cube Maximums" +msgstr "Capacités du cube" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label4..Caption +#: Decision Cube/mxdcube.dfm:304 +msgid "Active" +msgstr "Actif" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label7..Caption +#: Decision Cube/mxdcube.dfm:312 +msgid "Active+Needed" +msgstr "Actif+Nécessaire" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label9..Caption +#: Decision Cube/mxdcube.dfm:320 +msgid "&Dimensions" +msgstr "&Dimensions" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label6..Caption +#: Decision Cube/mxdcube.dfm:348 +msgid "&Summaries" +msgstr "&Récapitulatifs" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label12..Caption +#: Decision Cube/mxdcube.dfm:358 +msgid "&Cells" +msgstr "&Cellules" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label5..Caption +#: Decision Cube/mxdcube.dfm:376 +msgid "Maximum" +msgstr "Maximum" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..Label3..Caption +#: Decision Cube/mxdcube.dfm:384 +msgid "Current" +msgstr "En cours" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxDims....Height +#: Decision Cube/mxdcube.dfm:421 +msgid "Limit on the number of dimensions which can be loaded at one time\n" +msgstr "Limite du nombre de dimensions pouvant être chargés en une seule fois\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxSums..Hint +#: Decision Cube/mxdcube.dfm:430 +msgid "Limit on the number of summaries which can be loaded at one time" +msgstr "Limite du nombre récapitulatifs pouvant être chargés en une seule fois" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..MaxCells....Height +#: Decision Cube/mxdcube.dfm:443 +msgid "Limit on the number of storage cells which can be loaded at one time\n" +msgstr "Limite du nombre de cellules de sauvegarde pouvant être chargés en une seule fois\n" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Hint +#: Decision Cube/mxdcube.dfm:452 +msgid "Run a query to fetch information required to estimate cell usage" +msgstr "Lancer une requête pour obtenir les informations requises pour estimer l'utilisation des cellules" + +#. DSSCubeEditor..Pager..MemoryControl..CubeLimits..GetCellCounts..Caption +#: Decision Cube/mxdcube.dfm:453 +msgid "&Get Cell Counts" +msgstr "&Obtenir nb. de cellules" + +#. DimEditor..Caption +#. FieldsEditor..Caption +#: Decision Cube/mxdesign.dfm:6 +#: Editors/dsdesign.dfm:8 +msgid "Form1.Table1" +msgstr "Form1.Table1" + +#. SQLWindow..Caption +#: Decision Cube/mxdsql.dfm:6 +msgid "Form2" +msgstr "Form2" + +#. SQLWindow..Memo1....Lines.Strings +#: Decision Cube/mxdsql.dfm:32 +msgid "Memo1\n" +msgstr "Memo1\n" + +#. DSSQueryEditor..Caption +#: Decision Cube/mxdssqry.dfm:6 +msgid "Decision Query Editor" +msgstr "Editeur de requête de décision" + +#. DSSQueryEditor..Pager..Dimensions..Caption +#: Decision Cube/mxdssqry.dfm:23 +msgid "Dimensions/Summaries" +msgstr "Dimensions / récapitulatifs" + +#. DSSQueryEditor..Pager..Dimensions..Label2..Caption +#: Decision Cube/mxdssqry.dfm:30 +msgid "&Dimensions:" +msgstr "&Dimensions :" + +#. DSSQueryEditor..Pager..Dimensions..Label3..Caption +#: Decision Cube/mxdssqry.dfm:39 +msgid "&Summaries:" +msgstr "&Récapitulatifs :" + +#. DSSQueryEditor..Pager..Dimensions..Label4..Caption +#: Decision Cube/mxdssqry.dfm:48 +msgid "&List of Available Fields:" +msgstr "&Liste des champs disponibles :" + +#. DSSQueryEditor..Pager..Dimensions..Label5..Caption +#: Decision Cube/mxdssqry.dfm:57 +msgid "&Table:" +msgstr "&Table :" + +#. DSSQueryEditor..Pager..Dimensions..Label6..Caption +#: Decision Cube/mxdssqry.dfm:66 +msgid "Databas&e:" +msgstr "Ba&se :" + +#. DSSQueryEditor..Pager..Dimensions..Label7..Caption +#. CollectionEditor..ActionList1..AddCmd..Caption +#. LinkFields..AddButton..Caption +#. SocketForm..MainMenu1..miPorts..miAdd..Caption +#: Decision Cube/mxdssqry.dfm:76 +#: Editors/fldlinks.dfm:114 +#: Vcl/scktmain.dfm:345 +msgid "&Add" +msgstr "Aj&outer" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Hint +#: Decision Cube/mxdssqry.dfm:129 +msgid "List all fields or List only the fields in the query" +msgstr "Afficher tous les champs ou seulement ceux de la requête" + +#. DSSQueryEditor..Pager..Dimensions..SelectAllFields..Caption +#: Decision Cube/mxdssqry.dfm:130 +msgid "All &Fields" +msgstr "T&ous les champs" + +#. DSSQueryEditor..Pager..Dimensions..TableCombo..Hint +#: Decision Cube/mxdssqry.dfm:141 +msgid "Start a new query using a table from the database" +msgstr "Lancer une nouvelle requête sur une table de la base de données" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Hint +#: Decision Cube/mxdssqry.dfm:251 +msgid "Use count(*) to calculate averages (counts null values)" +msgstr "Utiliser count(*) pour calculer les moyennes (compte les valeurs nulles)" + +#. DSSQueryEditor..Pager..Dimensions..CountStarAvg..Caption +#: Decision Cube/mxdssqry.dfm:252 +msgid "Count (*) for Averages" +msgstr "Compter (*) pour moyennes" + +#. DSSQueryEditor..Pager..Query..Caption +#: Decision Cube/mxdssqry.dfm:261 +msgid "SQL Query" +msgstr "Requête SQL" + +#. DSSQueryEditor..Pager..Query..Label1..Caption +#: Decision Cube/mxdssqry.dfm:268 +msgid "&Query Text:" +msgstr "&Texte de requête :" + +#. DSSQueryEditor..Pager..Query..CancelQryMod..Caption +#: Decision Cube/mxdssqry.dfm:287 +msgid "&Cancel Edit" +msgstr "A&nnuler les modifications" + +#. DSSQueryEditor..Pager..Query..EditQry..Hint +#: Decision Cube/mxdssqry.dfm:296 +msgid "Type in the query directly" +msgstr "Saisir la requête directement" + +#. DSSQueryEditor..VQB..Hint +#: Decision Cube/mxdssqry.dfm:340 +msgid "Add/Join Tables and Create Field List with SQL Builder" +msgstr "Ajouter/fusionner les tables et créer la liste de champs avec SQL Builder" + +#. DSSQueryEditor..VQB..Caption +#: Decision Cube/mxdssqry.dfm:341 +msgid "SQL &Builder ..." +msgstr "&Constructeur SQL ..." + +#. DSSQueryEditor..AggPopup..count1..Caption +#: Decision Cube/mxdssqry.dfm:351 +msgid "&sum" +msgstr "&Somme" + +#. DSSQueryEditor..AggPopup..count2..Caption +#: Decision Cube/mxdssqry.dfm:355 +msgid "&count" +msgstr "&Nombre" + +#. DSSQueryEditor..AggPopup..average1..Caption +#: Decision Cube/mxdssqry.dfm:359 +msgid "&average" +msgstr "&Moyenne" + +#. ProgressDialog..Caption +#: Decision Cube/mxpbar.dfm:6 +msgid "ProgressDialog" +msgstr "Progression" + +#. ProgressDialog..CancelButton..Caption +#. DataBindForm..CancelBtn..Caption +#: Decision Cube/mxpbar.dfm:29 +msgid "&Cancel" +msgstr "&Annuler" + +#. ProgressDialog..StatusText..Caption +#: Decision Cube/mxpbar.dfm:40 +msgid "StatusText" +msgstr "StatusText" + +#. ConnEditForm..SourceofConnection..Caption +#: Property Editors/adoconed.dfm:49 +msgid " Source of Connection " +msgstr " Source de connexion " + +#. ConnEditForm..SourceofConnection..UseDataLinkFile..Caption +#: Property Editors/adoconed.dfm:57 +msgid "Use Data &Link File" +msgstr "Utiliser le &Fichier de Liaison de Données" + +#. ConnEditForm..SourceofConnection..Browse..Caption +#: Property Editors/adoconed.dfm:77 +msgid "&Browse..." +msgstr "&Parcourir..." + +#. ConnEditForm..SourceofConnection..UseConnectionString..Caption +#: Property Editors/adoconed.dfm:87 +msgid "Use &Connection String" +msgstr "Utiliser la chaîne de conne&xion" + +#. ConnEditForm..SourceofConnection..Build..Caption +#: Property Editors/adoconed.dfm:105 +msgid "B&uild..." +msgstr "&Construire..." + +#. ClientDataForm..Caption +#: Property Editors/cdsedit.dfm:6 +msgid "Client DataSet Data" +msgstr "Données DataSet client" + +#. ClientDataForm..GroupBox1..Caption +#: Property Editors/cdsedit.dfm:19 +msgid " Assign Data From " +msgstr " Affecter les données depuis" + +#. CollectionEditor..Caption +#: Property Editors/colnedit.dfm:10 +msgid "CollectionEditor" +msgstr "EditeurCollection" + +#. CollectionEditor..ToolBar1..ToolButton3..Caption +#: Property Editors/colnedit.dfm:41 +msgid "ToolButton3" +msgstr "ToolButton3" + +#. CollectionEditor..PopupMenu1..N2..Caption +#. FieldsEditor..LocalMenu..N1..Caption +#. SocketForm..PopupMenu..N1..Caption +#. SocketForm..MainMenu1..miPorts..N3..Caption +#. SocketForm..MainMenu1..Connections1..N2..Caption +#: Property Editors/colnedit.dfm:183 +#: Vcl/scktmain.dfm:324 +#: Vcl/scktmain.dfm:352 +#: Vcl/scktmain.dfm:368 +msgid "-" +msgstr "-" + +#. CollectionEditor..ActionList1..AddCmd..Hint +#: Property Editors/colnedit.dfm:190 +msgid "Add New" +msgstr "Ajouter un nouveau" + +#. CollectionEditor..ActionList1..DeleteCmd..Caption +#. DataBindForm..Panel1..DeleteBtn..Caption +#. FieldsEditor..LocalMenu..DeleteItem..Caption +#. LinkFields..DeleteButton..Caption +#. IndexFiles..GroupBox1..Delete..Caption +#: Property Editors/colnedit.dfm:196 +#: Editors/dsdesign.dfm:157 +#: Editors/fldlinks.dfm:123 +#: Editors/ixedit.dfm:43 +msgid "&Delete" +msgstr "S&upprimer" + +#. CollectionEditor..ActionList1..DeleteCmd..Hint +#: Property Editors/colnedit.dfm:198 +msgid "Delete Selected" +msgstr "Supprimer sélectionnés" + +#. CollectionEditor..ActionList1..MoveUpCmd..Caption +#: Property Editors/colnedit.dfm:205 +msgid "Move &Up" +msgstr "Vers le &haut" + +#. CollectionEditor..ActionList1..MoveUpCmd..Hint +#: Property Editors/colnedit.dfm:207 +msgid "Move Selected Up" +msgstr "Déplacer la sélection vers le haut" + +#. CollectionEditor..ActionList1..MoveDownCmd..Caption +#: Property Editors/colnedit.dfm:214 +msgid "Move Dow&n" +msgstr "Vers le &bas" + +#. CollectionEditor..ActionList1..MoveDownCmd..Hint +#: Property Editors/colnedit.dfm:216 +msgid "Move Selected Down" +msgstr "Déplacer la sélection vers le bas" + +#. CollectionEditor..ActionList1..SelectAllCmd..Caption +#. UpdateSQLEditForm..FieldListPopup..miSelectAll..Caption +#: Property Editors/colnedit.dfm:223 +msgid "&Select All" +msgstr "Tout &sélectionner" + +#. DBEditForm..GroupBox1..Caption +#: Property Editors/dbedit.dfm:18 +msgid " Database " +msgstr " Base de données" + +#. DBEditForm..GroupBox1..Label1..Caption +#: Property Editors/dbedit.dfm:25 +msgid "&Alias name:" +msgstr "Nom d'a&lias :" + +#. DBEditForm..GroupBox1..Label2..Caption +#: Property Editors/dbedit.dfm:33 +msgid "&Driver name:" +msgstr "Nom de &pilote :" + +#. DBEditForm..GroupBox1..Label3..Caption +#: Property Editors/dbedit.dfm:41 +msgid "&Parameter overrides:" +msgstr "&Remplacements paramètres :" + +#. DBEditForm..GroupBox1..Label4..Caption +#. DefineField..FieldGroup..FieldNameLabel..Caption +#: Property Editors/dbedit.dfm:49 +msgid "&Name:" +msgstr "&Nom :" + +#. DBEditForm..GroupBox1..DefaultsButton..Caption +#: Property Editors/dbedit.dfm:90 +msgid "D&efaults" +msgstr "&Défaut" + +#. DBEditForm..GroupBox1..ClearButton..Caption +#. LinkFields..ClearButton..Caption +#. IndexFiles..GroupBox1..Clear..Caption +#. PictureEditorDlg..GroupBox1..Clear..Caption +#: Property Editors/dbedit.dfm:99 +#: Editors/ixedit.dfm:53 +#: Editors/picedit.dfm:94 +msgid "&Clear" +msgstr "&Effacer" + +#. DBEditForm..GroupBox3..Caption +#: Property Editors/dbedit.dfm:116 +msgid " Options " +msgstr " Options " + +#. DBEditForm..GroupBox3..LoginPrompt..Caption +#: Property Editors/dbedit.dfm:123 +msgid "&Login prompt" +msgstr "In&vite de connexion" + +#. DBEditForm..GroupBox3..KeepConnection..Caption +#: Property Editors/dbedit.dfm:131 +msgid "&Keep inactive connection" +msgstr "&Conserver connexion inactive" + +#. InputReqDialog..Caption +#: Property Editors/dbinpreq.dfm:6 +msgid "Input Requested" +msgstr "Saisie requise" + +#. InputReqDialog..OKButton..Caption +#. LoginDialog..OKButton..Caption +#. DataBindForm..OkBtn..Caption +#. SQLEditForm..ButtonPanel..OkButton..Caption +#. StrEditDlg..OKButton..Caption +#. UpdateSQLEditForm..OkButton..Caption +#: Property Editors/dbinpreq.dfm:18 +#: Editors/dboleedt.dfm:109 +#: Editors/sqledit.dfm:94 +#: Editors/stredit.dfm:55 +#: Editors/updsqled.dfm:20 +msgid "&OK" +msgstr "&OK" + +#. InputReqDialog..NoPromptAgain..Caption +#: Property Editors/dbinpreq.dfm:48 +msgid "Don't Prompt Again" +msgstr "Ne plus demander" + +#. LoginDialog..Caption +#: Property Editors/dblogdlg.dfm:6 +msgid "Database Login" +msgstr "Connexion base de données" + +#. LoginDialog..Panel..Label3..Caption +#: Property Editors/dblogdlg.dfm:47 +msgid "Database:" +msgstr "Base de données :" + +#. LoginDialog..Panel..Panel1..Label1..Caption +#: Property Editors/dblogdlg.dfm:75 +msgid "&User Name:" +msgstr "&Utilisateur :" + +#. LoginDialog..Panel..Panel1..Label2..Caption +#: Property Editors/dblogdlg.dfm:83 +msgid "&Password:" +msgstr "&Mot de passe :" + +#. LoginDialog..Panel..Panel1..Password..PasswordChar +#: Property Editors/dblogdlg.dfm:100 +msgid "*" +msgstr "*" + +#. DataBindForm..Caption +#: Property Editors/dboleedt.dfm:6 +msgid "ActiveX Control Data Bindings Editor" +msgstr "Editeur de liaisons de données de contrôle ActiveX" + +#. DataBindForm..Panel1..Label1..Caption +#: Property Editors/dboleedt.dfm:29 +msgid "&Property Name:" +msgstr "&Nom de propriété :" + +#. DataBindForm..Panel1..Label2..Caption +#: Property Editors/dboleedt.dfm:37 +msgid "&Field Name:" +msgstr "&Nom de champ :" + +#. DataBindForm..Panel1..Label3..Caption +#: Property Editors/dboleedt.dfm:45 +msgid "Bo&und Properties to Fields:" +msgstr "&Propriétés liées aux champs :" + +#. DataBindForm..Panel1..BindBtn..Caption +#: Property Editors/dboleedt.dfm:73 +msgid "<- &Bind ->" +msgstr "<- &Lier ->" + +#. DataBindForm..Panel1..ClearBtn..Caption +#: Property Editors/dboleedt.dfm:99 +msgid "C&lear" +msgstr "&Effacer" + +#. AddFields..Caption +#: Property Editors/dsadd.dfm:6 +msgid "Add Fields" +msgstr "Ajout de champs" + +#. AddFields..GroupBox1..Caption +#: Property Editors/dsadd.dfm:46 +msgid "Available fields" +msgstr "Champs disponibles" + +#. AssociateAttributes..Caption +#: Property Editors/dsattra.dfm:5 +msgid "Associate attributes" +msgstr "Association d'attributs" + +#. AssociateAttributes..GroupBox1..Caption +#: Property Editors/dsattra.dfm:51 +msgid "Attribute set name" +msgstr "Nom ensemble d'attributs" + +#. SaveAttributesAs..Caption +#: Property Editors/dsattrs.dfm:5 +msgid "Save %s attributes as" +msgstr "Enregistrer attributs %s sous" + +#. SaveAttributesAs..Label1..Caption +#: Property Editors/dsattrs.dfm:25 +msgid "&Attribute set name:" +msgstr "&Nom d'ensemble d'attributs :" + +#. SaveAttributesAs..Label2..Caption +#: Property Editors/dsattrs.dfm:33 +msgid "&Based on:" +msgstr "&Basé sur :" + +#. DefineField..Caption +#: Property Editors/dsdefine.dfm:5 +msgid "New Field" +msgstr "Nouveau champ" + +#. DefineField..LookupGroup..Caption +#: Property Editors/dsdefine.dfm:18 +msgid "Lookup definition" +msgstr "Définition de la référence" + +#. DefineField..LookupGroup..DatasetLabel..Caption +#: Property Editors/dsdefine.dfm:25 +msgid "D&ataset:" +msgstr "&Dataset :" + +#. DefineField..LookupGroup..KeyFieldsLabel..Caption +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label3..Caption +#: Property Editors/dsdefine.dfm:34 +msgid "&Key Fields:" +msgstr "Champs c&lé :" + +#. DefineField..LookupGroup..LookupKeysLabel..Caption +#: Property Editors/dsdefine.dfm:43 +msgid "Look&up Keys:" +msgstr "Clés de ré&férence :" + +#. DefineField..LookupGroup..ResultFieldLabel..Caption +#: Property Editors/dsdefine.dfm:52 +msgid "&Result Field:" +msgstr "Champ rés&ultat :" + +#. DefineField..FieldGroup..Caption +#: Property Editors/dsdefine.dfm:133 +msgid "Field properties" +msgstr "Propriétés du champ" + +#. DefineField..FieldGroup..ComponentNameLabel..Caption +#: Property Editors/dsdefine.dfm:140 +msgid "C&omponent:" +msgstr "Com&posant :" + +#. DefineField..FieldGroup..FieldTypeLabel..Caption +#: Property Editors/dsdefine.dfm:156 +msgid "&Type:" +msgstr "T&ype :" + +#. DefineField..FieldGroup..SizeEditLabel..Caption +#: Property Editors/dsdefine.dfm:164 +msgid "&Size:" +msgstr "&Taille :" + +#. DefineField..FieldKind..Caption +#: Property Editors/dsdefine.dfm:206 +msgid "Field type" +msgstr "Type de champ" + +#. DefineField..FieldKind....Items.Strings +#: Property Editors/dsdefine.dfm:213 +msgid "" +"&Data\n" +"&Calculated\n" +"&Lookup\n" +msgstr "" +"&Donnée\n" +"&Calcul\n" +"&Lookup\n" + +#. FieldsEditor..FieldListBox..Hint +#: Property Editors/dsdesign.dfm:81 +msgid "Fields" +msgstr "Champs" + +#. FieldsEditor..AggListBox..Hint +#: Property Editors/dsdesign.dfm:99 +msgid "Aggregates" +msgstr "Globaux" + +#. FieldsEditor..LocalMenu..AddItem..Caption +#: Property Editors/dsdesign.dfm:119 +msgid "&Add fields..." +msgstr "&Ajouter des champs..." + +#. FieldsEditor..LocalMenu..NewItem..Caption +#: Property Editors/dsdesign.dfm:125 +msgid "&New field..." +msgstr "&Nouveau champ..." + +#. FieldsEditor..LocalMenu..Addallfields1..Caption +#: Property Editors/dsdesign.dfm:131 +msgid "Add all &fields" +msgstr "Ajouter tous les c&hamps" + +#. FieldsEditor..LocalMenu..CutItem..Caption +#: Property Editors/dsdesign.dfm:139 +msgid "Cu&t" +msgstr "&Couper" + +#. FieldsEditor..LocalMenu..CopyItem..Caption +#: Property Editors/dsdesign.dfm:145 +msgid "&Copy" +msgstr "&Copier" + +#. FieldsEditor..LocalMenu..PasteItem..Caption +#: Property Editors/dsdesign.dfm:151 +msgid "&Paste" +msgstr "C&oller" + +#. FieldsEditor..LocalMenu..SelectAllItem..Caption +#: Property Editors/dsdesign.dfm:163 +msgid "Se&lect all" +msgstr "&Tout sélectionner" + +#. LinkFields..Caption +#: Property Editors/fldlinks.dfm:6 +msgid "Field Link Designer" +msgstr "Concepteur de liaison de champs" + +#. LinkFields..Label30..Caption +#: Property Editors/fldlinks.dfm:35 +msgid "D&etail Fields" +msgstr "Champs &détail" + +#. LinkFields..Label31..Caption +#: Property Editors/fldlinks.dfm:44 +msgid "&Master Fields" +msgstr "Champs &maître" + +#. LinkFields..IndexLabel..Caption +#: Property Editors/fldlinks.dfm:53 +msgid "A&vailable Indexes" +msgstr "&Index disponibles :" + +#. LinkFields..Label2..Caption +#: Property Editors/fldlinks.dfm:61 +msgid "&Joined Fields" +msgstr "&Champs joints" + +#. IndexFiles..Caption +#. IndexFiles..GroupBox1..Caption +#: Property Editors/ixedit.dfm:5 +msgid "Index Files" +msgstr "Fichiers index" + +#. IndexFiles..GroupBox1..Add..Caption +#: Property Editors/ixedit.dfm:34 +msgid "&Add..." +msgstr "Aj&outer..." + +#. IndexFiles..OpenDialog....OnClick +#: Property Editors/ixedit.dfm:92 +msgid "dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" +msgstr "dBASE Multiple Index (*.MDX)|*.mdx|dBase Index (*.NDX)|*.ndx|FoxPro Index (*.CDX)|*.cdx\n" + +#. PictureEditorDlg..Caption +#: Property Editors/picedit.dfm:6 +msgid "Picture Editor" +msgstr "Editeur d'images" + +#. PictureEditorDlg..GroupBox1..Load..Caption +#. StrEditDlg..StringEditorMenu..LoadItem..Caption +#: Property Editors/picedit.dfm:76 +msgid "&Load..." +msgstr "&Charger..." + +#. PictureEditorDlg..GroupBox1..Save..Caption +#. StrEditDlg..StringEditorMenu..SaveItem..Caption +#: Property Editors/picedit.dfm:85 +msgid "&Save..." +msgstr "Enregi&strer..." + +#. PictureEditorDlg..OpenDialog....OnClick +#. PictureEditorDlg..SaveDialog....Top +#: Property Editors/picedit.dfm:104 +msgid "All (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf\n" +msgstr "Tous les fichiers (*.bmp;*.ico;*.emf;*.wmf)|*.bmp;*.ico;*.emf;*.wmf|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf\n" + +#. SQLEditForm..Caption +#: Property Editors/sqledit.dfm:5 +msgid "CommandText Editor" +msgstr "Editeur de CommandText" + +#. SQLEditForm..TopPanel..TableListLabel..Caption +#: Property Editors/sqledit.dfm:52 +msgid "&Tables:" +msgstr "&Tables :" + +#. SQLEditForm..TopPanel..SQLLabel..Caption +#: Property Editors/sqledit.dfm:60 +msgid "&SQL:" +msgstr "&SQL :" + +#. SQLEditForm..MetaInfoPanel..TableListPanel..AddTableButton..Caption +#: Property Editors/sqledit.dfm:165 +msgid "Add T&able to SQL" +msgstr "Ajouter la ta&ble à SQL" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..FieldListLabel..Caption +#: Property Editors/sqledit.dfm:183 +msgid "&Fields:" +msgstr "&Champs :" + +#. SQLEditForm..MetaInfoPanel..FieldsPanel..AddFieldButton..Caption +#: Property Editors/sqledit.dfm:203 +msgid "Add F&ield to SQL" +msgstr "Ajouter le c&hamp à SQL" + +#. StrEditDlg..Caption +#: Property Editors/stredit.dfm:5 +msgid "String List editor" +msgstr "Editeur de liste de chaînes" + +#. StrEditDlg..LineCount..Caption +#: Property Editors/stredit.dfm:29 +msgid "0 lines" +msgstr "0 lignes" + +#. StrEditDlg..CodeWndBtn..Caption +#. StrEditDlg..StringEditorMenu..CodeEditorItem..Caption +#: Property Editors/stredit.dfm:36 +msgid "&Code Editor..." +msgstr "Editeur de &code..." + +#. StrEditDlg..OpenDialog..DefaultExt +#: Property Editors/stredit.dfm:84 +msgid "TXT" +msgstr "TXT" + +#. StrEditDlg..OpenDialog....DefaultExt +#. StrEditDlg..SaveDialog....Left +#: Property Editors/stredit.dfm:88 +msgid "Text files (*.TXT)|*.TXT|Config files (*.SYS;*.INI)|*.SYS;*.INI|Batch files (*.BAT)|*.BAT|All files (*.*)|*.*\n" +msgstr "Fichiers textes (*.TXT)|*.TXT|Fichiers de configuration (*.SYS;*.INI)|*.SYS;*.INI|Fichiers Batch (*.BAT)|*.BAT|Tous les fichiers (*.*)|*.*\n" + +#. StrEditDlg..OpenDialog..Title +#: Property Editors/stredit.dfm:89 +msgid "Load string list" +msgstr "Charger la liste de chaînes" + +#. StrEditDlg..SaveDialog..Title +#: Property Editors/stredit.dfm:97 +msgid "Save string list" +msgstr "Enregistrer la liste de chaînes" + +#. UpdateSQLEditForm..PageControl..FieldsPage..Caption +#: Property Editors/updsqled.dfm:54 +msgid "Options" +msgstr "Options" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Caption +#: Property Editors/updsqled.dfm:60 +msgid " SQL Generation " +msgstr " Génération SQL" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label1..Caption +#: Property Editors/updsqled.dfm:67 +msgid "Table &Name:" +msgstr "&Nom de table :" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..Label4..Caption +#: Property Editors/updsqled.dfm:83 +msgid "Update &Fields:" +msgstr "C&hamps mise à jour :" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GenerateButton..Caption +#: Property Editors/updsqled.dfm:123 +msgid "&Generate SQL" +msgstr "&Générer SQL" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..PrimaryKeyButton..Caption +#: Property Editors/updsqled.dfm:132 +msgid "Select &Primary Keys" +msgstr "&Sélectionner clés primaires" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..DefaultButton..Caption +#: Property Editors/updsqled.dfm:141 +msgid "&Dataset Defaults" +msgstr "&Défaut pour DataSet" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..QuoteFields..Caption +#: Property Editors/updsqled.dfm:151 +msgid "&Quote Field Names" +msgstr "Noms de champs &entre guillemets" + +#. UpdateSQLEditForm..PageControl..FieldsPage..GroupBox1..GetTableFieldsButton..Caption +#: Property Editors/updsqled.dfm:160 +msgid "Get &Table Fields" +msgstr "O&btenir les champs" + +#. UpdateSQLEditForm..PageControl..SQLPage..Caption +#: Property Editors/updsqled.dfm:167 +msgid "SQL" +msgstr "SQL" + +#. UpdateSQLEditForm..PageControl..SQLPage..Label2..Caption +#: Property Editors/updsqled.dfm:173 +msgid "S&QL Text:" +msgstr "Texte S&QL :" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType..Caption +#: Property Editors/updsqled.dfm:190 +msgid "Statement Type" +msgstr "Type d'instruction" + +#. UpdateSQLEditForm..PageControl..SQLPage..StatementType....Items.Strings +#: Property Editors/updsqled.dfm:197 +msgid "" +"&Modify\n" +"&Insert\n" +"&Delete\n" +msgstr "" +"&Modifier\n" +"&Insérer\n" +"&Effacer\n" + +#. UpdateSQLEditForm..FieldListPopup..miClearAll..Caption +#: Property Editors/updsqled.dfm:214 +msgid "&Clear All" +msgstr "Tout &effacer" + +#. HTTPServer......Name +#: Vcl/httpintr.dfm:6 +msgid "Interpreter" +msgstr "interpréteur" + +#. SocketForm..Caption +#: Vcl/scktmain.dfm:6 +msgid "Borland Socket Server" +msgstr "Borland Socket Server" + +#. SocketForm..Pages..PropPage..PortGroup..Caption +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#. SocketForm..Panel1..HeaderControl1......Text +#: Vcl/scktmain.dfm:38 +msgid "Port" +msgstr "Port" + +#. SocketForm..Pages..PropPage..PortGroup..Label1..Caption +#: Vcl/scktmain.dfm:46 +msgid "&Listen on Port:" +msgstr "à &l'écoute du port:" + +#. SocketForm..Pages..PropPage..PortGroup..PortDesc....AutoSize +#: Vcl/scktmain.dfm:60 +msgid "Many values of Port are associated by convention with a particular service such as ftp or http. Port is the ID of the connection on which the server listens for client requests. \n" +msgstr "Beaucoup de numéros de port sont associés par défaut avec des services tels que FTP ou HTTP. Le numéro de port est l'identifiant de connexion assigné à un serveur de service donné, réagissant aux demandes issues de processus client.\n" + +#. SocketForm..Pages..PropPage..ThreadGroup..Caption +#: Vcl/scktmain.dfm:92 +msgid "Thread Caching" +msgstr "Cache de Thread" + +#. SocketForm..Pages..PropPage..ThreadGroup..Label4..Caption +#: Vcl/scktmain.dfm:100 +msgid "&Thread Cache Size:" +msgstr "Taille du cache de &Thread:" + +#. SocketForm..Pages..PropPage..ThreadGroup..ThreadDesc....AutoSize +#: Vcl/scktmain.dfm:113 +msgid "Thread Cache Size is the maximum number of threads that can be reused for new client connections.\n" +msgstr "La taille du cache de Thread est le nombre maximum de Threads réutilisables pour traiter de nouvelles connextions des processus clients.\n" + +#. SocketForm..Pages..PropPage..InterceptGroup..Caption +#: Vcl/scktmain.dfm:145 +msgid "Intercept GUID" +msgstr "GUID d'interception" + +#. SocketForm..Pages..PropPage..InterceptGroup..Label5..Caption +#: Vcl/scktmain.dfm:152 +msgid "&GUID:" +msgstr "&GUID:" + +#. SocketForm..Pages..PropPage..InterceptGroup..GUIDDesc....AutoSize +#: Vcl/scktmain.dfm:164 +msgid "Intercept GUID is the GUID for a data interceptor COM object. See help for the TSocketConnection for details.\n" +msgstr "Une GUID d'interception est la GUID d'un objet COM d'interception de données. Voir l'aide en ligne pour les détails.\n" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Caption +#: Vcl/scktmain.dfm:180 +msgid "Timeout" +msgstr "dépassement de temps" + +#. SocketForm..Pages..PropPage..TimeoutGroup..Label7..Caption +#: Vcl/scktmain.dfm:188 +msgid "&Inactive Timeout:" +msgstr "Désact&iver le dépassement de temps" + +#. SocketForm..Pages..PropPage..TimeoutGroup..TimeoutDesc....AutoSize +#: Vcl/scktmain.dfm:201 +msgid "Inactive Timeout specifes the number of minutes a client can be inactive before being disconnected. (0 indicates infinite)\n" +msgstr "Le temps de dépassement correspond à la durée d'inactivité d'un client, en minutes, après laquelle celui-ci sera déconnecté automatiquement (0 pour une durée infinie)\n" + +#. SocketForm..Pages..StatPage..Caption +#: Vcl/scktmain.dfm:239 +msgid "Users" +msgstr "Utilisateurs" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:252 +msgid "IP Address" +msgstr "Adresse IP" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:256 +msgid "Host" +msgstr "Host" + +#. SocketForm..Pages..StatPage..ConnectionList......Caption +#: Vcl/scktmain.dfm:260 +msgid "Last Activity" +msgstr "Dernière action" + +#. SocketForm..PopupMenu..miProperties..Caption +#: Vcl/scktmain.dfm:327 +msgid "&Properties" +msgstr "&Propriétés" + +#. SocketForm..MainMenu1..miPorts..Caption +#: Vcl/scktmain.dfm:343 +msgid "&Ports" +msgstr "&Ports" + +#. SocketForm..MainMenu1..miPorts..miExit..Caption +#: Vcl/scktmain.dfm:355 +msgid "&Exit" +msgstr "%Sortir" + +#. SocketForm..MainMenu1..Connections1..Caption +#: Vcl/scktmain.dfm:360 +msgid "&Connections" +msgstr "&connexion" + +#. SocketForm..ActionList1..ApplyAction..Caption +#: Vcl/scktmain.dfm:379 +msgid "&Apply" +msgstr "Appli&quer" + +#. SocketForm..ActionList1..DisconnectAction..Caption +#: Vcl/scktmain.dfm:384 +msgid "&Disconnect" +msgstr "&Déconnecter" + +#. SocketForm..ActionList1..ShowHostAction..Caption +#: Vcl/scktmain.dfm:389 +msgid "&Show Host Name" +msgstr "&Afficher les noms des Host" + +#. SocketForm..ActionList1..RemovePortAction..Caption +#: Vcl/scktmain.dfm:394 +msgid "&Remove" +msgstr "&Supprimer" + +#. SocketForm..ActionList1..RegisteredAction..Caption +#: Vcl/scktmain.dfm:399 +msgid "&Registered Objects Only" +msgstr "Uniquement les objets &recensés" + diff --git a/win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po b/win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po new file mode 100644 index 000000000..ae9e099fb --- /dev/null +++ b/win32/gui-2/locale/fr/LC_MESSAGES/gpsbabel.po @@ -0,0 +1,397 @@ +msgid "" +msgstr "" +"Project-Id-Version: GPSBabel command line program\n" +"POT-Creation-Date: 2005-11-19 01:14\n" +"PO-Revision-Date: 2006-10-29 19:18+0100\n" +"Last-Translator: Lilian Morinon \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Midnight Commander\n" +"X-Poedit-Language: French\n" + +msgid "(integer sec or 'auto') Barograph to GPS time diff" +msgstr "(entier sec ou 'auto') Barograph de différence temporelle GPS" + +msgid "(USR input) Break segments into separate tracks" +msgstr "(entrée USR) Séparer les segment en plusieurs traces" + +msgid "(USR output) Merge into one segmented track" +msgstr "(sortie USR) Fusionner en une trace segmentée" + +msgid "Ad-hoc closed icon name" +msgstr "Nom de l'icône pour Ad-hoc fermé" + +msgid "Ad-hoc open icon name" +msgstr "Nom de l'icône pour Ad-hoc ouvert" + +msgid "Allow whitespace synth. shortnames" +msgstr "Autoriser les espaces dans les noms courts" + +msgid "Altitudes are absolute and not clamped to ground" +msgstr "Les altitudes sont absolue et idépendantes du sol" + +msgid "Append icon_descr to description" +msgstr "Ajouter icon_descr à la description" + +msgid "Base URL for link tag in output" +msgstr "URL de base pour l'étiquette de lien en sortie" + +msgid "Basename prepended to URL on output" +msgstr "Nom de base à utiliser pour l'URL de sortie" + +msgid "Category name (Cache)" +msgstr "Nom de la catégorie" + +msgid "Category number to use for written waypoints" +msgstr "" + +msgid "Color for lines or mapnotes" +msgstr "Couleur des lignes ou des notes" + +msgid "Command unit to power itself down" +msgstr "Ordonner au GPS de s'éteindre" + +msgid "Complete date-free tracks with given date (YYYYMMDD)." +msgstr "Ajouter une date donnée (AAAAMMJJ) à une trace sans horodatage" + +msgid "Create waypoints from geocache log entries" +msgstr "Créer des waypoints à partir des entrés de log géocache" + +msgid "Database name" +msgstr "Nom de la base de données" + +msgid "Database name (filename)" +msgstr "Nom de la base de données (nom de fichier)" + +msgid "Datum (default=NAD27)" +msgstr "Datum (défaut=NAD27)" + +msgid "Days after which points are considered old" +msgstr "Nombre de jours après lesquels les points sont considérés comme anciens" + +msgid "Decimal seconds to pause between groups of strings" +msgstr "" + +msgid "Default category on output (1..16)" +msgstr "Catégorie par défaut en sortie (1..16)" + +msgid "Default icon name" +msgstr "Nom d'icone par défaut" + +msgid "Default speed for waypoints (knots/hr)" +msgstr "" + +msgid "Degrees output as 'ddd', 'dmm'(default) or 'dms'" +msgstr "" + +msgid "Delete all waypoints" +msgstr "Supprimer tous les waypoints" + +msgid "Display labels on track and routepoints (default = 1)" +msgstr "" + +msgid "Distance unit [m=metric, s=statute]" +msgstr "" + +msgid "Do not add geocache data to description" +msgstr "Ne pas ajouter d'inforamtion de geocache à la description" + +msgid "Draw extrusion line from trackpoint to ground" +msgstr "" + +msgid "Drop route points that do not have an equivalent waypoint (hidden points)" +msgstr "Eliminer les points de route qui n'ont pas de waypoint équivallent (points cachés)" + +msgid "Encrypt hints using ROT13" +msgstr "Encrypter les signes en ROT13" + +msgid "Encrypt hints with ROT13" +msgstr "Encrypter les signes avec ROT13" + +msgid "Erase device data after download" +msgstr "" + +msgid "Export linestrings for tracks and routes" +msgstr "Exporter les chaînes de caractères pour les traces et les routes" + +msgid "Export placemarks for tracks and routes" +msgstr "Exporter les marqueurs pour les traces et les routes" + +msgid "Full path to XCSV style file" +msgstr "Chemin complet du fichier de modèle de XCSV" + +msgid "Generate file with lat/lon for centering map" +msgstr "Générer le fichier avec les infos de centrage de carte (lat/lon)" + +msgid "Give points (waypoints/route points) a default radius (proximity)" +msgstr "Donner un rayon de proximité par défaut aux points (waypoints/points de route)" + +msgid "GPS datum (def. WGS 84)" +msgstr "" + +msgid "Height in pixels of map" +msgstr "Hauteur de la carte en pixels" + +msgid "Ignore event marker icons" +msgstr "Ignorer les icones marqueurs d'événements" + +msgid "Include extended data for trackpoints (default = 1)" +msgstr "" + +msgid "Include groundspeak logs if present" +msgstr "Inclure les logs groundspeak si disponible" + +msgid "Include only via stations in route" +msgstr "Inclure seulement les étapes dans la route" + +msgid "Include short name in bookmarks" +msgstr "Inclure les noms courts dans les signets" + +msgid "Index of name field in .dbf" +msgstr "Index du champ nom dans le .dbf" + +msgid "Index of route (if more the one in source)" +msgstr "" + +msgid "Index of route to write (if more the one in source)" +msgstr "Index des routes à écrire (si plusieurs sources)" + +msgid "Index of route/track to write (if more the one in source)" +msgstr "Index des routes/traces à écrire (si plusieurs sources)" + +msgid "Index of track (if more the one in source)" +msgstr "" + +msgid "Index of track to write (if more the one in source)" +msgstr "Index des traces à écrire (si plusieurs sources)" + +msgid "Index of URL field in .dbf" +msgstr "Index du champ URL dans le .dbf" + +msgid "Infrastructure closed icon name" +msgstr "Nom de l'icône pour l'Infrastructure fermée" + +msgid "Infrastructure open icon name" +msgstr "Nom de l'icône pour l'Infrastructure ouverte" + +msgid "Keep turns if simplify filter is used" +msgstr "Garder les virages si le filtre simplifié est utilisé" + +msgid "Length of generated shortnames" +msgstr "Longueur des nom courts générés" + +msgid "Length of generated shortnames (default 16)" +msgstr "Longueur des nom courts générés (défaut : 16)" + +msgid "Line color, specified in hex AABBGGRR" +msgstr "Couleur de la ligne, spécifié en hexadécimal AABBGGRR" + +msgid "Make synth. shortnames unique" +msgstr "Les noms courts sont tous différents" + +msgid "MapSend version TRK file to generate (3,4)" +msgstr "" + +msgid "Margin for map. Degrees or percentage" +msgstr "Marge de la carte. Degrés ou pourcentage" + +msgid "Marker type for new points" +msgstr "Type de marqueur pour les nouveaux points" + +msgid "Marker type for old points" +msgstr "Type de marqueur pour les anciens points" + +msgid "Marker type for unfound points" +msgstr "Type de marqueur pour les points non trouvés" + +msgid "Max length of waypoint name to write" +msgstr "Longueur maximum du nom du waypoint" + +msgid "Max number of comments to write (maxcmts=200)" +msgstr "Nombre maximum de commentaires à écrire (maxcmts=200)" + +msgid "Max shortname length when used with -s" +msgstr "Longueur maximum du nom court lorsque utilisé avec l'option -s" + +msgid "Max synthesized shortname length" +msgstr "Longueur max. de noms courts générés" + +msgid "Merge output with existing file" +msgstr "Fusionner la sortie avec un fichier existant" + +msgid "Name of the 'unassigned' category" +msgstr "Nom de la catégorie 'non assignée'" + +msgid "New name for the route" +msgstr "Nouveau nom pour la route" + +msgid "No separator lines between waypoints" +msgstr "Supprimer les lignes de séparation en les waypoints" + +msgid "No whitespace in generated shortnames" +msgstr "Supprimer les espaces dans les noms courts générés" + +msgid "Non-stealth encrypted icon name" +msgstr "Ne pas récupérer les noms d'icones encryptés" + +msgid "Non-stealth non-encrypted icon name" +msgstr "Ne pas récupérer les noms d'icones non encryptés" + +msgid "Numeric value of bitrate (baud=4800)" +msgstr "Valeur numérique de la vitesse de transfert (4800 bauds)" + +msgid "Omit Placer name" +msgstr "Omettre le nom du Placer" + +msgid "Only read turns; skip all other points" +msgstr "Lire seulement les virages; ne pas tenire compte des autres points" + +msgid "Path to HTML style sheet" +msgstr "Chemin vers une feuille de style HTML" + +msgid "Precision of coordinates" +msgstr "Précision des coordonnées" + +msgid "Radius for circles" +msgstr "Rayon des cercles" + +msgid "Radius of our big earth (default 6371000 meters)" +msgstr "Rayon de la terre (défaut : 6371000 mètres)" + +msgid "Read control points as waypoint/route/none" +msgstr "Lire les points de contrôle en temps au waypoint/route/rien" + +msgid "Read/Write date format (i.e. DDMMYYYY)" +msgstr "" + +msgid "Read/Write date format (i.e. yyyy/mm/dd)" +msgstr "Lire/Ecrire le format de date (i.e. YYYY/MM/DD)" + +msgid "Read/write GPGGA sentences" +msgstr "" + +msgid "Read/write GPGSA sentences" +msgstr "" + +msgid "Read/write GPRMC sentences" +msgstr "" + +msgid "Read/write GPVTG sentences" +msgstr "" + +msgid "Read/Write time format (i.e. HH:mm:ss xx)" +msgstr "Lire/Ecrire le format horaire (i.e. HH:mm:ss xx)" + +msgid "Retain at most this number of position points (0 = unlimited)" +msgstr "" + +msgid "Return current position as a waypoint" +msgstr "Renvoyer la position courante en tant que waypoint" + +msgid "Road type changes" +msgstr "" + +msgid "Shortname is MAC address" +msgstr "Le nom court est l'adresse MAC" + +msgid "Speed in bits per second of serial port (baud=4800)" +msgstr "" + +msgid "Split input into separate files" +msgstr "" + +msgid "Split into multiple routes at turns" +msgstr "Séparer en plusieurs routes à chaque virage" + +msgid "Stealth encrypted icon name" +msgstr "Récupérer les noms d'icones encryptés" + +msgid "Stealth non-encrypted icon name" +msgstr "Récupérer les noms d'icones non encryptés" + +msgid "String to separate concatenated address fields (default=\", \")" +msgstr "Chaine de caractère pour séparer les champs d'adresse (\", \" par défaut)" + +msgid "Suppress labels on generated pins" +msgstr "Supprimer les labels des points créés" + +msgid "Suppress retired geocaches" +msgstr "Suypprimer les géocaches désactivées" + +msgid "Suppress separator lines between waypoints" +msgstr "" + +msgid "Suppress use of handshaking in name of speed" +msgstr "Supprimer les controles pour améliorer les performances" + +msgid "Suppress whitespace in generated shortnames" +msgstr "" + +msgid "Symbol to use for point data" +msgstr "Symbole à utiliser pour les données de type point" + +msgid "Synthesize track times" +msgstr "Simplifier l'horodatage des traces" + +msgid "Target GPX version for output" +msgstr "Version du fichier GPX pour la sortie" + +msgid "Temperature unit [c=Celsius, f=Fahrenheit]" +msgstr "" + +msgid "The icon description is already the marker" +msgstr "Les description de l'icon est identique au marqueur" + +msgid "Type of .an1 file" +msgstr "" + +msgid "Units for altitude (f)eet or (m)etres" +msgstr "" + +msgid "Units used when writing comments ('s'tatute or 'm'etric)" +msgstr "" + +msgid "UPPERCASE synth. shortnames" +msgstr "Noms courts en MAJUSCULE" + +msgid "Use depth values on output (default is ignore)" +msgstr "Utiliser les valeurs de profondeur sur la sortie (par défaut : ignorer)" + +msgid "Use proximity values on output (default is ignore)" +msgstr "Utiliser les valeurs de proximité sur la sortie (par défaut : ignorer)" + +msgid "Use shortname instead of description" +msgstr "Utiliser le nom court au lieu de la description" + +msgid "Version of gdb file to generate (1,2)" +msgstr "Version du fichier gdb à créer (1,2)" + +msgid "Version of mapsource file to generate (3,4,5)" +msgstr "Version du fichier mapsource à créer (3,4,5)" + +msgid "Waypoint background color" +msgstr "Couleur de fond du Waypoint" + +msgid "Waypoint foreground color" +msgstr "Couleur du Waypoint" + +msgid "Waypoint type" +msgstr "" + +msgid "Width in pixels of map" +msgstr "Largeur de la carte en pixels" + +msgid "Width of lines, in pixels" +msgstr "Largeur des lignes en pixels" + +msgid "Write timestamps with offset x to UTC time" +msgstr "Ecrire l'horodatage avec un décalage de x par rapport à l'heure UTC" + +msgid "Write tracks compatible with Carto Exploreur" +msgstr "Ecrire des traces compatibles avec CartoExploreur" + +msgid "Zoom level to reduce points" +msgstr "Niveau de zoom pour réduire les points" + diff --git a/win32/gui-2/main.dfm b/win32/gui-2/main.dfm new file mode 100644 index 0000000000000000000000000000000000000000..6f27fe4d93da9780913ad0d6bc47e1d5f9c90a5b GIT binary patch literal 37152 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 A$^ZZW literal 0 HcmV?d00001 diff --git a/win32/gui-2/main.pas b/win32/gui-2/main.pas new file mode 100644 index 000000000..ddc2c57cc --- /dev/null +++ b/win32/gui-2/main.pas @@ -0,0 +1,1362 @@ +unit main; + +{ + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +interface + +uses + gnugettext, TypInfo, delphi, + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, Buttons, ExtCtrls, + common, utils, ImgList, ActnList, Menus, ComCtrls, ToolWin; + +type + TfrmMain = class(TForm) + pnTop: TPanel; + pnBottom: TPanel; + cbWaypoints: TCheckBox; + cbRoutes: TCheckBox; + cbTracks: TCheckBox; + lbWhat: TLabel; + OpenDialog: TOpenDialog; + SaveDialog: TSaveDialog; + wptInputOK: TSpeedButton; + ImageList1: TImageList; + wptOutputOK: TSpeedButton; + rteInputOK: TSpeedButton; + rteOutputOK: TSpeedButton; + trkInputOK: TSpeedButton; + trkOutputOK: TSpeedButton; + ActionList1: TActionList; + acConvert: TAction; + btnFilter: TBitBtn; + acFilterSelect: TAction; + btnProcess: TBitBtn; + memoOutput: TMemo; + stbMain: TStatusBar; + MainMenu1: TMainMenu; + mnuFile: TMenuItem; + mnuExit: TMenuItem; + acFileExit: TAction; + mnuHelp: TMenuItem; + acHelpAbout: TAction; + acHelpIntro: TAction; + Intro1: TMenuItem; + About1: TMenuItem; + mnuReadme: TMenuItem; + acHelpReadme: TAction; + N1: TMenuItem; + mnuOptions: TMenuItem; + mnuSynthesizeShortNames: TMenuItem; + Filter1: TMenuItem; + N2: TMenuItem; + acOptionsSourceFormat: TAction; + acOptionsTargetFormat: TAction; + forsourceformat1: TMenuItem; + fortargetformat1: TMenuItem; + acFileClearMemo: TAction; + N3: TMenuItem; + Clearoutput1: TMenuItem; + acFinalizeDropDowns: TAction; + N4: TMenuItem; + mnuOptionsForceDataType: TMenuItem; + acOptionsEnableCharactersetTransformation: TAction; + Enablecharactersettransformation1: TMenuItem; + gbInput: TGroupBox; + sbOpenFile: TSpeedButton; + lbInputOpts: TLabel; + lbInputFormat: TLabel; + lbInputFile: TLabel; + edInputOpts: TComboBox; + edInputFile: TComboBox; + chbInputDevice: TCheckBox; + cbInputLang: TComboBox; + cbInputFormatDevice: TComboBox; + cbInputFormat: TComboBox; + cbInputDevice: TComboBox; + btnInputOpts: TSpeedButton; + gbOutput: TGroupBox; + cbOutputFormatDevice: TComboBox; + chbOutputDevice: TCheckBox; + lbOutputOpts: TLabel; + edOutputOpts: TComboBox; + btnOutputOpts: TSpeedButton; + lbOutputFormat: TLabel; + cbOutputFormat: TComboBox; + lbOutputFile: TLabel; + edOutputFile: TComboBox; + sbSaveFile: TSpeedButton; + cbOutputLang: TComboBox; + cbOutputDevice: TComboBox; + acFileOutputToScreen: TAction; + Outputtoscreen1: TMenuItem; + acDebugCreatePo: TAction; + mnuDebug: TMenuItem; + Createoptionspo1: TMenuItem; + acFileChangeLanguage: TAction; + Changelanguage1: TMenuItem; + N5: TMenuItem; + acFileExportCSV: TAction; + Createoptionscsv1: TMenuItem; + File1: TMenuItem; + Createoptionscsv2: TMenuItem; + sdOptional: TSaveDialog; + procedure FormShow(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure OpenButtonClick(Sender: TObject); + procedure edInputFileChange(Sender: TObject); + procedure CheckInput; + procedure edOutputFileChange(Sender: TObject); + procedure cbWaypointsClick(Sender: TObject); + procedure cbRoutesClick(Sender: TObject); + procedure cbTracksClick(Sender: TObject); + procedure sbSaveFileClick(Sender: TObject); + procedure acConvertExecute(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure acFilterSelectExecute(Sender: TObject); + procedure acFileExitExecute(Sender: TObject); + procedure acHelpAboutExecute(Sender: TObject); + procedure chbInputDeviceClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure chbOutputDeviceClick(Sender: TObject); + procedure acHelpReadmeExecute(Sender: TObject); + procedure mnuSynthesizeShortNamesClick(Sender: TObject); + procedure edOutputFileKeyPress(Sender: TObject; var Key: Char); + procedure cbInputFormatDeviceChange(Sender: TObject); + procedure cbOutputFormatDeviceChange(Sender: TObject); + procedure cbInputFormatChange(Sender: TObject); + procedure cbOutputFormatChange(Sender: TObject); + procedure acOptionsSourceFormatExecute(Sender: TObject); + procedure acOptionsTargetFormatExecute(Sender: TObject); + procedure btnInputOptsClick(Sender: TObject); + procedure acFileClearMemoExecute(Sender: TObject); + procedure acFinalizeDropDownsExecute(Sender: TObject); + procedure mnuOptionsForceDataTypeClick(Sender: TObject); + procedure acOptionsEnableCharactersetTransformationExecute( + Sender: TObject); + procedure acFileOutputToScreenExecute(Sender: TObject); + procedure acDebugCreatePoExecute(Sender: TObject); + procedure acFileChangeLanguageExecute(Sender: TObject); + procedure acFileExportCSVExecute(Sender: TObject); + procedure cbOutputDeviceChange(Sender: TObject); + procedure cbInputDeviceChange(Sender: TObject); + private + { Private-Deklarationen } + FCaps: TCapabilities; + FOpts: TOptions; + FLang: TStringList; + FFirstShow: Boolean; + FOutHandmade: Boolean; + FFmtIn, FFmtOut: string; + procedure AddToOutput(const Str: string); + procedure AddToOutputFmt(const Format: string; const Args: array of const); + procedure ComboBoxChanged(const Format: string; IsInput, IsFile: Boolean); + procedure DoOnIdle(Sender: TObject; var Done: Boolean); + procedure EnableOptions(const Version: string); + function HandleOptions(const Format: string; AObject: TObject; IsInput: Boolean): Boolean; + function HandleOptionsDlg(const Format: string; var str: string; IsInput: Boolean): Boolean; + procedure HandleParams; + procedure HistoryChanged(Box: TComboBox; Swap: Boolean = False); + procedure InitCombo(Target: TComboBox; IsInput, ForDevice: Boolean); + procedure InitializeSerialPorts; + procedure LoadLanguages; + procedure LoadFileFormats; + procedure LoadVersion; + procedure RefreshDesign(FirstTime: Boolean = False); + procedure WMOPTIONSCHANGED(var Msg: TMessage); message WM_OPTIONS_CHANGED; + procedure WMSTARTUP(var Msg: TMessage); message WM_STARTUP; + procedure StoreProfiles; + public + { Public-Deklarationen } + end; + +var + frmMain: TfrmMain; + +implementation + +uses + filter, about, readme, options, select; + +{$R *.DFM} + +procedure FixAlign(Control: TControl; ShiftLeft: Integer; + RightOfMe: TControl = nil); +var + Right: Integer; +begin + Right := Control.Parent.Left + Control.Parent.Width; + + if Assigned(RightOfMe) then + ShiftLeft := ShiftLeft + RightOfMe.Width; + + if (akLeft in Control.Anchors) then + Control.Width := Right - Control.Left - ShiftLeft + else if (akRight in Control.Anchors) then + Control.Left := Right - Control.Width - ShiftLeft; +end; + +function ComboBoxSelect(AComboBox: TComboBox; const Item: string): Boolean; +var + i: Integer; +begin + i := AComboBox.Items.IndexOf(Item); + AComboBox.ItemIndex := i; + Result := (i >= 0); +end; + +{ TfrmMain } + +procedure TfrmMain.RefreshDesign(FirstTime: Boolean); +begin + if not(FirstTime) then + ReTranslateComponent(SELF); + +// VS_FF_DEBUG The file contains debugging information or is compiled with debugging features enabled. +// VS_FF_INFOINFERRED The file's version structure was created dynamically; +// therefore, some of the members in this structure may be empty or incorrect. +// This flag should never be set in a file's VS_VERSION_INFO data. +// VS_FF_PATCHED The file has been modified and is not identical to the original shipping file of the same version number. +// VS_FF_PRERELEASE The file is a development version, not a commercially released product. +// VS_FF_PRIVATEBUILD The file was not built using standard release procedures. If this flag is set, +// the StringFileInfo structure should contain a PrivateBuild entry. +// VS_FF_SPECIALBUILD The file was built by the original company using standard release procedures +// but is a variation of the normal file of the same version number. +// If this flag is set, the StringFileInfo structure should contain a SpecialBuild + + if (CFixedFileinfo.dwFileFlags and VS_FF_DEBUG <> 0) then + Caption := Format('%s (%s)', [Caption, _('Internal development release')]) + else if (CFixedFileinfo.dwFileFlags and VS_FF_PRERELEASE <> 0) then + Caption := Format('%s (%s)', [Caption, _('BETA')]) + else if (CFixedFileinfo.dwFileFlags and VS_FF_PRIVATEBUILD <> 0) then + Caption := Format('%s (%s)', [Caption, _('Private release')]) + else if (CFixedFileinfo.dwFileFlags and VS_FF_SPECIALBUILD <> 0) then + Caption := Format('%s (%s)', [Caption, _('Special release')]); + + FixAlign(sbOpenFile, 8); + FixAlign(sbSaveFile, 8); + FixAlign(edInputFile, 8, sbOpenFile); + FixAlign(edOutputFile, 8, sbSaveFile); + + FixAlign(cbInputLang, 8); + btnInputOpts.Left := lbInputOpts.Left + lbInputOpts.Width + 8; + edInputOpts.Left := btnInputOpts.Left + btnInputOpts.Width + 4; + edInputOpts.Width := cbInputLang.Left - edInputOpts.Left - 4; + + FixAlign(cbOutputLang, 8); + btnOutputOpts.Left := lbOutputOpts.Left + lbOutputOpts.Width + 8; + edOutputOpts.Left := btnOutputOpts.Left + btnOutputOpts.Width + 4; + edOutputOpts.Width := cbOutputLang.Left - edOutputOpts.Left - 4; + + FixAlign(btnProcess, 8); + FixAlign(btnFilter, 16, btnProcess); + + gbInput.Caption := '>>> ' + _('Input'); + gbOutput.Caption := '<<< ' + _('Output'); + chbInputDevice.Caption := '[' + chbInputDevice.Caption + ']'; + chbOutputDevice.Caption := '[' + chbOutputDevice.Caption + ']'; + + acOptionsSourceFormat.Caption := _('Input') + ': ' + FFmtIn; + acOptionsTargetFormat.Caption := _('Output') + ': ' + FFmtOut; + + btnInputOpts.Caption := ''; + btnOutputOpts.Caption := ''; +end; + +procedure TfrmMain.FormCreate(Sender: TObject); +begin + MakeFirstTranslation(Self); + + FFirstShow := True; + + TP_Ignore(mnuDebug, 'mnuDebug'); +{$IFOPT D-} + mnuDebug.Visible := False; +{$ENDIF} + LoadLanguages; + + memoOutput.Lines.Clear; + + FCaps := TCapabilities.Create; + FOpts := TOptions.Create(FCaps); + + OpenDialog.InitialDir := ReadProfile(OpenDialog.Tag); + SaveDialog.InitialDir := ReadProfile(SaveDialog.Tag); + + if not ComboBoxSelect(cbInputDevice, ReadProfile(cbInputDevice.Tag)) then + cbInputDevice.ItemIndex := 0; + + if not ComboBoxSelect(cbOutputDevice, ReadProfile(cbOutputDevice.Tag)) then + cbOutputDevice.ItemIndex := 0; + + edInputFile.Text := ReadProfile(edInputFile.Tag); + + cbInputLang.ItemIndex := 0; + cbOutputLang.ItemIndex := 0; + + Application.OnIdle := Self.DoOnIdle; + + RefreshDesign(True); + HandleParams; +end; + +procedure TfrmMain.LoadLanguages; +begin + FLang := TStringList.Create; + + DefaultInstance.GetListOfLanguages('default', FLang); + if (FLang.IndexOf('en') < 0) then + FLang.Add('en'); + acFileChangeLanguage.Visible := (FLang.Count > 1); +end; + +procedure TfrmMain.LoadFileFormats; +var + l: TStrings; +begin + l := TStringList.Create; + try + + if (gpsbabel_vfmt >= '001.002.008') then + gpsbabel('-^3', l) + else if (gpsbabel_vfmt >= '001.002.005') then + gpsbabel('-^2', l) + else begin + MessageBox(0, PChar(gpsbabel_vfmt), 'Release info', MB_OK); + MessageDlg(_('The file "gpsbabel.exe" found in current directory is too old!'), + mtError, [mbOK], 0); + Halt(1); + end; + + FCaps.List := l; + FOpts.List := l; + InitCombo(cbInputFormatDevice, False, True); + InitCombo(cbOutputFormatDevice, True, True); + InitCombo(cbInputFormat, True, False); + InitCombo(cbOutputFormat, False, False); + finally + l.Free; + end; +end; + +procedure TfrmMain.FormShow(Sender: TObject); +begin + if not(FFirstShow) then Exit; + + FFirstShow := False; + PostMessage(SELF.Handle, WM_STARTUP, 0, 0); // keep sure our window is visible +end; + +procedure TfrmMain.WMSTARTUP(var Msg: TMessage); +var + s: string; +begin +// gpsbabel_ini := TIniFile.Create('gpsbabel.ini'); + LoadVersion; + EnableOptions(gpsbabel_vfmt); + LoadFileFormats; + + // ? valid README form + s := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html'; + acHelpReadme.Enabled := FileExists(s) or (frmReadme.Memo.Lines.Count > 0); + + InitializeSerialPorts; +end; + +procedure TfrmMain.InitCombo(Target: TComboBox; IsInput, ForDevice: Boolean); +var + i: Integer; + OK: Boolean; + s: string; +begin + for i := 0 to FCaps.Count - 1 do + begin + if (ForDevice and not(FCaps.IsDevice(i))) then Continue; + if not(ForDevice) and not FCaps.IsFile(i) then Continue; + + if (IsInput) then + OK := FCaps.CanReadAny(i) + else + OK := FCaps.CanWriteAny(i); + if OK then + Target.Items.Add(FCaps.GetDescr(i)); + end; + + s := ReadProfile(Target.Tag); + ComboBoxSelect(Target, s); + + ComboBoxChanged(Target.Text, IsInput, not(ForDevice)); +end; + +procedure TfrmMain.OpenButtonClick(Sender: TObject); +var + s: string; +begin + OpenDialog.Filter := ''; + OpenDialog.DefaultExt := '*.*'; + + if (cbInputFormat.Text <> '') then + s := cbInputFormat.Text + '|*.' + FCaps.GetExt(cbInputFormat.Text) + '|'; + s := s + _('All files|*.*'); + + OpenDialog.Filter := s; + if not SELF.OpenDialog.Execute then Exit; + + edInputFile.Text := OpenDialog.FileName; + CheckInput; +end; + +procedure TfrmMain.ComboBoxChanged(const Format: string; IsInput, IsFile: Boolean); +var + caps: Integer; + ext: string; + ac: TAction; +begin + caps := FCaps.GetCaps(Format); + ext := FCaps.GetExt(Format); + if IsFile and FOutHandmade and (ext = '') then + begin + ext := SysUtils.ExtractFileExt(edOutputFile.Text); + if (ext <> '') and (ext[1] = '.') then Delete(ext, 1, 1); + end; + + if IsInput then + begin + FFmtIn := Format; + wptInputOK.Enabled := (caps and 1 <> 0); + trkInputOK.Enabled := (caps and 4 <> 0); + rteInputOK.Enabled := (caps and 16 <> 0); + end + else + begin + FFmtOut := Format; + wptOutputOK.Enabled := (caps and 2 <> 0); + trkOutputOK.Enabled := (caps and 8 <> 0); + rteOutputOK.Enabled := (caps and 32 <> 0); + if IsFile and (edOutputFile.Text <> '') and (edOutputFile.Text <> '-') then + begin + if (ext <> '') then FOutHandmade := False; + edOutputFile.Text := SysUtils.ChangeFileExt(edOutputFile.Text, '.' + ext); + end; + end; + + CheckInput; + + if IsInput then + begin + edInputOpts.Text := ''; + edInputOpts.Items.Clear; + + ac := acOptionsSourceFormat; + acOptionsSourceFormat.Caption := _('Input') + ': ' + Format; + btnInputOpts.Caption := ''; +// ImageList1.GetBitmap(11, btnInputOpts.Glyph); + end + else begin + edOutputOpts.Text := ''; + edOutputOpts.Items.Clear; + + ac := acOptionsTargetFormat; + acOptionsTargetFormat.Caption := _('Output') + ': ' + Format; + btnOutputOpts.Caption := ''; +// ImageList1.GetBitmap(11, btnOutputOpts.Glyph); + end; + + ac.Enabled := FOpts.HasFormatOpts(Format); + if ac.Enabled then + begin + ac.Hint := SysUtils.Format(_('Select and edit options for "%s"'), [Format]); + end + else + begin + ac.Hint := SysUtils.Format(_('No options available for "%s"'), [Format]); + end; +end; + +procedure TfrmMain.edInputFileChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.CheckInput; +begin + acConvert.Enabled := + (cbWaypoints.Checked or cbRoutes.Checked or cbTracks.Checked) + and + ( + ((chbInputDevice.Checked and + (cbInputDevice.Text <> '') and + (cbInputFormatDevice.Text <> '')) + or + (not(chbInputDevice.Checked) and + (edInputFile.Text <> '') and + (cbInputFormat.Text <> ''))) + and + ((chbOutputDevice.Checked and + (cbOutputDevice.Text <> '') and + (cbOutputFormatDevice.Text <> '')) + or + (not(chbOutputDevice.Checked) and + (edOutputFile.Text <> '') and + (cbOutputFormat.Text <> ''))) + ); +end; + +procedure TfrmMain.edOutputFileChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbWaypointsClick(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbRoutesClick(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbTracksClick(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.sbSaveFileClick(Sender: TObject); +var + s: string; +begin + SaveDialog.Filter := ''; + SaveDialog.DefaultExt := '*.*'; + + if (cbOutputFormat.Text <> '') then + s := cbOutputFormat.Text + '|*.' + FCaps.GetExt(cbOutputFormat.Text) + '|'; + s := s + _('All files|*.*'); + + SaveDialog.Filter := s; + if not SELF.SaveDialog.Execute then Exit; + + edOutputFile.Text := SaveDialog.FileName; + CheckInput; +end; + +procedure TfrmMain.acConvertExecute(Sender: TObject); +var + cmdline: string; + list: TStrings; + CSave: TCursor; + str: TStream; + s: string; + i: Integer; + IFormat, OFormat: string; + Fatal: Boolean; + +begin + btnProcess.Enabled := False; + try + acFinalizeDropDownsExecute(nil); + + cmdline := ''; + if gpsbabel_knows_inifile then cmdline := '-p ""'; + + if chbInputDevice.Checked then + IFormat := FCaps.GetName(cbInputFormatDevice.Text) + else + IFormat := FCaps.GetName(cbInputFormat.Text); + if chbOutputDevice.Checked then + OFormat := FCaps.GetName(cbOutputFormatDevice.Text) + else + OFormat := FCaps.GetName(cbOutputFormat.Text); + + if cbWaypoints.Checked then cmdline := cmdline + ' -w'; + if cbRoutes.Checked then cmdline := cmdline + ' -r'; + if cbTracks.Checked then cmdline := cmdline + ' -t'; + + if mnuSynthesizeShortNames.Checked then cmdline := cmdline + ' -s'; + + if chbInputDevice.Checked then + begin + s := SysUtils.AnsiLowerCase(cbInputDevice.Text) + ':'; +// if (s = 'usb:') then +// s := s + '-1'; + end + else + begin + s := edInputFile.Text; + if not(FileExists(s)) then + raise eGPSBabelError.CreateFmt(_('File %s not found.'), [s]); + s := '"' + s + '"'; + end; + + // Input character set + + if acOptionsEnableCharactersetTransformation.Checked and + (cbInputLang.ItemIndex > 0) then + cmdline := Format('%s -c %s', + [cmdline, cbInputLang.Text]); + + if (Trim(edInputOpts.Text) <> '') then + cmdline := Format('%s -i %s,%s -f %s', + [cmdline, IFormat, Trim(edInputOpts.Text), s]) + else + cmdline := Format('%s -i %s -f %s', + [cmdline, IFormat, s]); + + if mnuOptionsForceDataType.Checked then + begin + s := ''; + if not(cbWaypoints.Checked) then + s := s + ',waypoints'; + if not(cbRoutes.Checked) then + s := s + ',routes'; + if not(cbTracks.Checked) then + s := s + ',tracks'; + if (s <> '') then + cmdline := Format('%s -x nuketypes%s', [cmdline, s]); + end; + + // Add filter options + + if (frmFilter <> nil) then + cmdline := cmdline + frmFilter.CmdLine; + + // Output character set + + if acOptionsEnableCharactersetTransformation.Checked and + (cbOutputLang.ItemIndex > 0) then + cmdline := Format('%s -c %s', + [cmdline, cbOutputLang.Text]); + + if (chbOutputDevice.Checked) then + begin + if (cbOutputDevice.Text = 'SCREEN') then + s := '-' + else begin + s := AnsiLowerCase(cbOutputDevice.Text + ':'); +// if (s = 'usb:') then +// s := s + '-1'; + end; + end + else begin + s := edOutputFile.Text; + + if (s <> '-') then + begin + if FileExists(s) then + begin + if (Windows.MessageBox(SELF.Handle, + PChar(Format(_('File "%s" exists ! Overwrite ?'), [s])), + PChar(_('Warning')), MB_YESNO) <> IDYES) then Exit; + end + else + begin + str := TFileStream.Create(s, fmCreate); + str.Free; + end; + s := '"' + s + '"'; + end + else + s := '-'; + end; + + if (Trim(edOutputOpts.Text) <> '') then + cmdline := Format('%s -o %s,%s -F %s', + [cmdline, OFormat, Trim(edOutputOpts.Text), s]) + else + cmdline := Format('%s -o %s -F %s', + [cmdline, OFormat, s]); + + while (cmdline[1] = ' ') do System.Delete(cmdline, 1, 1); + + s := 'gpsbabel.exe ' + cmdline; + AddToOutput(s); + + CSave := Cursor; + list := TStringList.Create; + try + Cursor := crHourGlass; + Application.ProcessMessages; + Sleep(50); + + if not gpsbabel(cmdline, list, @Fatal, False) then + raise eGPSBabelError.Create(_('Could not run "gpsbabel.exe"!')); + + if (list.Count > 0) then + begin + AddToOutput(''); + AddToOutput(string(list.GetText)); + end; + + if (Fatal) then + MessageDlg(_('Sorry, gpsbabel.exe reported problems!'), mtError, [mbOK], 0) + else + MessageDlg(Format(_('Converted successfully from "%s" to "%s".'), [IFormat, OFormat]), + mtInformation, [mbOK], 0); + + finally + + Cursor := CSave; + list.Free; + + end; + + finally + btnProcess.Enabled := True; + end; +end; + +procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + CanClose := True; +end; + +procedure TfrmMain.acFilterSelectExecute(Sender: TObject); +begin + if (frmFilter = nil) then + Application.CreateForm(TfrmFilter, frmFilter); + if not(frmFilter.ShowModal = mrOk) then Exit; +end; + +procedure TfrmMain.AddToOutput(const Str: string); +begin + memoOutput.Lines.Add(Str); +end; + +procedure TfrmMain.AddToOutputFmt(const Format: string; + const Args: array of const); +begin + AddToOutput(SysUtils.Format(Format, Args)); +end; + +procedure TfrmMain.acFileExitExecute(Sender: TObject); +begin + PostMessage(SELF.Handle, WM_CLOSE, 0, 0); +end; + +procedure TfrmMain.LoadVersion; +var + l, l2: TStringList; + i: Integer; + s: string; + cx: PChar; + + procedure SpaceDelimited(const str: string; list: TStrings); + var + s: string; + cin, cend, cx: PChar; + begin + s := Trim(str); + cin := PChar(s); + cend := cin + StrLen(cin); + while (cin < cend) do + begin + while (cin^ = ' ') do cin := cin + 1; + cx := StrScan(cin, ' '); + if (cx = nil) then cx := cend; + cx^ := #0; + list.Add(string(cin)); + cin := cx + 1; + end; + end; + +begin + gpsbabel_major := 0; + gpsbabel_minor := 0; + gpsbabel_release := 0; + + l := TStringList.Create; + try + + try + if not gpsbabel('-p "" -V', l) then + PostMessage(Self.Handle, WM_QUIT, 0, 0); + except + on E: Exception do + begin + ShowException(E, nil); + PostMessage(Self.Handle, WM_QUIT, 0, 0); + end; + end; + + for i := 0 to l.Count - 1 do + begin + s := Trim(l.Strings[i]); + if (Copy(AnsiUpperCase(s), 1, 8) = 'GPSBABEL') then + begin + l2 := TStringList.Create; + try + SpaceDelimited(s, l2); + gpsbabel_version := l2[2]; + cx := PChar(gpsbabel_version); + gpsbabel_major := atoi(cx); + cx := StrScan(cx, '.'); + if (cx <> nil) then + begin + gpsbabel_minor := atoi(cx + 1); + cx := StrScan(cx + 1, '.'); + if (cx <> nil) then + gpsbabel_release := atoi(cx + 1); + end; + + gpsbabel_vfmt := Format('%3.3d.%3.3d.%3.3d', [ + gpsbabel_major, gpsbabel_minor, gpsbabel_release]); + + s := Format(_('GPSBabel, version %s'), [gpsbabel_version]); + stbMain.Panels[0].Text := s; + stbMain.Panels[0].Width := stbMain.Canvas.TextWidth(s) + + Trunc((Length(s)* 1.5)); + Break; + finally + l2.Free; + end; + end; + end; + + finally + l.Free; + end; +end; + +procedure TfrmMain.acHelpAboutExecute(Sender: TObject); +begin + if (frmAbout = nil) then + Application.CreateForm(TfrmAbout, frmAbout); + frmAbout.ShowModal; +end; + +procedure TfrmMain.chbInputDeviceClick(Sender: TObject); +begin + if not(Sender is TCheckBox) then Exit; + + if TCheckBox(Sender).Checked then + begin + edInputFile.Visible := False; + sbOpenFile.Visible := False; + cbInputFormat.Visible := False; + cbInputDevice.Visible := True; + cbInputFormatDevice.Visible := True; + lbInputFile.Caption := _('Port'); + FFmtIn := cbInputFormatDevice.Text; + end + else + begin + cbInputFormat.Visible := True; + cbInputFormatDevice.Visible := False; + cbInputDevice.Visible := False; + edInputFile.Visible := True; + cbInputDevice.Visible := False; + sbOpenFile.Visible := True; + lbInputFile.Caption := _('File'); + FFmtIn := cbInputFormat.Text; + end; + acOptionsSourceFormat.Caption := _('Input') + ': ' + FFmtIn; + acOptionsSourceFormat.Enabled := (FOpts.FormatOpts(FFmtIn) <> nil); + CheckInput; +end; + +procedure TfrmMain.StoreProfiles; +var + s: string; +begin + s := SysUtils.ExtractFilePath(edInputFile.Text); + if (s <> '') then + StoreProfile(OpenDialog.Tag, s); + s := SysUtils.ExtractFilePath(edOutputFile.Text); + if (s <> '') then + StoreProfile(SaveDialog.Tag, s); + StoreProfile(cbInputFormat.Tag, cbInputFormat.Text); + StoreProfile(cbOutputFormat.Tag, cbOutputFormat.Text); + StoreProfile(cbInputDevice.Tag, cbInputDevice.Text); + StoreProfile(cbInputFormatDevice.Tag, cbInputFormatDevice.Text); + StoreProfile(cbOutputDevice.Tag, cbOutputDevice.Text); + StoreProfile(cbOutputFormatDevice.Tag, cbOutputFormatDevice.Text); + StoreProfile(edInputFile.Tag, edInputFile.Text); + StoreProfile(edOutputFile.Tag, edOutputFile.Text); +end; + +procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); +begin + StoreProfiles; +end; + +procedure TfrmMain.chbOutputDeviceClick(Sender: TObject); +begin + if not(Sender is TCheckBox) then Exit; + + if TCheckBox(Sender).Checked then + begin + cbOutputFormatDevice.Visible := True; + cbOutputDevice.Visible := True; + edOutputFile.Visible := False; + sbSaveFile.Visible := False; + cbOutputFormat.Visible := False; + lbOutputFile.Caption := _('Port'); + FFmtOut := cbOutputFormatDevice.Text; + end + else + begin + cbOutputFormat.Visible := True; + sbSaveFile.Visible := True; + edOutputFile.Visible := True; + cbOutputDevice.Visible := False; + cbOutputFormatDevice.Visible := False; + lbOutputFile.Caption := _('File'); + FFmtOut := cbOutputFormat.Text; + end; + acOptionsTargetFormat.Caption := _('Output') + ': ' + FFmtOut; + acOptionsTargetFormat.Enabled := (FOpts.FormatOpts(FFmtOut) <> nil); + CheckInput; +end; + +procedure TfrmMain.acHelpReadmeExecute(Sender: TObject); +var + s: string; +begin + s := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html'; + if FileExists(s) then + WinOpenFile(s, '') // new gpsbabel.html + else begin // show the old readme + if (frmReadme = nil) then + Application.CreateForm(TfrmReadme, frmReadme); + frmReadme.ShowModal; + end; +end; + +procedure TfrmMain.mnuSynthesizeShortNamesClick(Sender: TObject); +begin + mnuSynthesizeShortNames.Checked := not(mnuSynthesizeShortNames.Checked); +end; + +procedure TfrmMain.edOutputFileKeyPress(Sender: TObject; var Key: Char); +begin + FOutHandmade := True; +end; + +procedure TfrmMain.cbInputFormatDeviceChange(Sender: TObject); +begin + ComboBoxChanged(cbInputFormatDevice.Text, True, False); +end; + +procedure TfrmMain.cbOutputFormatDeviceChange(Sender: TObject); +begin + ComboBoxChanged(cbOutputFormatDevice.Text, False, False); +end; + +procedure TfrmMain.cbInputFormatChange(Sender: TObject); +begin + ComboBoxChanged(cbInputFormat.Text, True, True); +end; + +procedure TfrmMain.cbOutputFormatChange(Sender: TObject); +begin + ComboBoxChanged(cbOutputFormat.Text, False, True); +end; + +procedure TfrmMain.acOptionsSourceFormatExecute(Sender: TObject); +begin + if chbInputDevice.Checked then + HandleOptions(cbInputFormatDevice.Text, edInputOpts, True) + else + HandleOptions(cbInputFormat.Text, edInputOpts, True) +end; + +procedure TfrmMain.DoOnIdle(Sender: TObject; var Done: Boolean); +begin + inherited; + acFileClearMemo.Enabled := (memoOutput.Lines.Count > 0); + Done := True; +end; + +procedure TfrmMain.EnableOptions(const Version: string); +begin + if (Version >= '001.002.008') then + mnuOptionsForceDataType.Enabled := True; + if (version >= '001.002.007') then + acOptionsEnableCharactersetTransformation.Enabled := True; +end; + +function TfrmMain.HandleOptions(const Format: string; AObject: TObject; IsInput: Boolean): Boolean; +var + s: string; + ok: Boolean; +begin + s := GetStrProp(AObject, 'Text'); + if HandleOptionsDlg(Format, s, IsInput) then + begin + SetStrProp(AObject, 'Text', s); + Result := True; + end + else + Result := False; +end; + +function TfrmMain.HandleOptionsDlg(const Format: string; var str: string; IsInput: Boolean): Boolean; +begin + Application.CreateForm(TfrmOptions, frmOptions); + try + frmOptions.Caption := SysUtils.Format(_('Options for "%s"'), [Format]); + frmOptions.FIsInput := IsInput; + frmOptions.Opts := FOpts.FormatOpts(Format); + frmOptions.OptsStr := str; + Result := (frmOptions.ShowModal = mrOk); + if (Result) then + begin + str := frmOptions.OptsStr; + PostMessage(Self.Handle, WM_OPTIONS_CHANGED, 0, 0); + end; + finally + frmOptions.Release; + end; +end; + +procedure TfrmMain.acOptionsTargetFormatExecute(Sender: TObject); +begin + if chbOutputDevice.Checked then + HandleOptions(cbOutputFormatDevice.Text, edOutputOpts, False) + else + HandleOptions(cbOutputFormat.Text, edOutputOpts, False); +end; + +procedure TfrmMain.btnInputOptsClick(Sender: TObject); +begin + acOptionsSourceFormat.Execute; +end; + +procedure TfrmMain.acFileClearMemoExecute(Sender: TObject); +begin + memoOutput.Clear; +end; + +procedure TfrmMain.acFinalizeDropDownsExecute(Sender: TObject); +var + i, j: Integer; + c: TComponent; + cb: TComboBox; +begin + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if not(c is TComboBox) then Continue; + cb := Pointer(c); + if (cb.Style <> csDropDown) or (cb.Text = '') then Continue; + j := cb.Items.IndexOf(cb.Text); + if (j < 0) then + cb.Items.Insert(0, cb.Text); + end; +end; + +procedure TfrmMain.WMOPTIONSCHANGED(var Msg: TMessage); +begin + acFinalizeDropDowns.Execute; +end; + +procedure TfrmMain.mnuOptionsForceDataTypeClick(Sender: TObject); +begin + mnuOptionsForceDataType.Checked := not(mnuOptionsForceDataType.Checked); +end; + +procedure TfrmMain.acOptionsEnableCharactersetTransformationExecute( + Sender: TObject); +begin + acOptionsEnableCharactersetTransformation.Checked := not ( + acOptionsEnableCharactersetTransformation.Checked); + + cbInputLang.Enabled := acOptionsEnableCharactersetTransformation.Checked; + cbOutputLang.Enabled := acOptionsEnableCharactersetTransformation.Checked; +end; + +procedure TfrmMain.acFileOutputToScreenExecute(Sender: TObject); +begin + if (chbOutputDevice.Checked) then + begin + chbOutputDevice.Checked := False; + chbOutputDeviceClick(chbOutputDevice); + Application.ProcessMessages; + end; + + acFileOutputToScreen.Checked := not (acFileOutputToScreen.Checked); + if acFileOutputToScreen.Checked then + begin + chbOutputDevice.Enabled := False; + HistoryChanged(edOutputFile); + edOutputFile.Text := '-'; + edOutputFile.Enabled := False; + edOutputFile.Color := clInactiveBorder; + sbSaveFile.Enabled := False; + end + else + begin + edOutputFile.Color := edInputFile.Color; + chbOutputDevice.Enabled := True; + edOutputFile.Enabled := True; + HistoryChanged(edOutputFile, True); + sbSaveFile.Enabled := True; + end; + CheckInput; +end; + +procedure TfrmMain.HandleParams; +var + i: Integer; + s: string; +begin + for i := 1 to ParamCount do + begin + s := ParamStr(i); + if (i = 0) then + edInputFile.Text := s + else begin + if (i = 1) then + edInputFile.Items.Add(edInputFile.Text); + edInputFile.Items.Add(s); + end; + end; +end; + +procedure TfrmMain.HistoryChanged(Box: TComboBox; Swap: Boolean); +var + index: Integer; + item: string; +begin + item := Trim(Box.Text); + if (item <> '') then + begin + index := Box.Items.IndexOf(item); + if (index < 0) then + Box.Items.Insert(0, item) + else + Box.Items.Move(index, 0); + end; + if (swap and (Box.Items.Count > 1)) then + Box.ItemIndex := 1; +end; + +procedure TfrmMain.acDebugCreatePoExecute(Sender: TObject); +var + l: TStringList; + i, j, len: Integer; + s: string; + f: TFileStream; + + procedure WriteLn(Str: string); + begin + Str := Str + #13#10; + f.Write(PChar(Str)^, Length(Str)); + end; + +begin + l := TStringList.Create; + try + FOpts.DebugGetHints(l); + f := TFileStream.Create('..\gpsbabel.po', fmCreate); + try + WriteLn('msgid ""'); + WriteLn('msgstr ""'); + WriteLn(''); + + for i := 0 to l.Count - 1 do + begin + s := l.Strings[i]; + len := Length(s); + for j := len downto 1 do + begin + if (s[j] = '"') then + begin + Insert('\', s, j); + end; + end; + WriteLn('msgid "' + s + '"'); + WriteLn('msgstr ""'); + WriteLn(''); + end; + MessageDlg('..\gpsbabel.po created!', mtInformation, [mbok], 0); + finally + f.Free; + end; + finally + l.Free; + end; +end; + +procedure TfrmMain.acFileChangeLanguageExecute(Sender: TObject); +var + lang: string; + form: TForm; + title: string; +begin + Title := _('Choose language') + ' ' + _('for GUIBabelGUI'); + if SelectLanguage(Title, FLang, lang) and + (CompareText(lang, Copy(GetCurrentLanguage, 1, 2)) <> 0) then + begin + StoreProfile(11, lang); + UseLanguage(lang); + RefreshDesign; + form := frmFilter; + frmFilter := nil; + if (Form <> nil) then Form.Release; + form := frmReadme; + frmReadme := nil; + if (Form <> nil) then Form.Release; + form := frmAbout; + frmAbout := nil; + if (Form <> nil) then Form.Release; + end; +end; + +procedure TfrmMain.acFileExportCSVExecute(Sender: TObject); +const + init_dir: string = ''; + file_name: string = 'gpsbabel.csv'; +var + i, j, len: Integer; + s, lang, curr_lang: string; + o: POption; + f: TFileStream; + l: TStrings; + + function _translate(const Domain, MsgID: string): WideString; + var + i: Integer; + tmp: WideString; + boo: Boolean; + begin + tmp := MsgID; + Result := dgettext(Domain, tmp); + if (Result = tmp) then + Result := _(MsgID); + if (Result = tmp) then + Result := '' + else begin + boo := False; + i := Length(Result); + while (i >= 1) do + begin + if (Result[i] = '"') then + begin + Insert('"', Result, i); + boo := True; + end; + Dec(i); + end; + if (boo) then + begin + memoOutput.Lines.Add('Warning: ''"'' found in translation!'); + memoOutput.Lines.Add(Result); + end; + end; + end; + + procedure _line(const Prefix, MsgID: string); + begin + UniWriteLn(f, Prefix + ',"' + MsgID + '","' + + _translate(GPSBabel_Domain, MsgID) + '"'); + end; + +begin + if not SelectLanguage( + _('Choose language') + ' ' + _('for export'), + FLang, lang) then Exit; + + if (sdOptional.InitialDir = '') then + GetDir(0, init_dir); + + sdOptional.InitialDir := init_dir; + sdOptional.FileName := file_name; + + if not(sdOptional.Execute) then Exit; + + init_dir := sdOptional.InitialDir; + file_name := sdOptional.FileName; + + curr_lang := GetCurrentLanguage; + try + + UseLanguage(lang); + + f := TFileStream.Create(sdOptional.FileName, fmCreate); + try + + UniWriteLn(f, Format('code,en,%s', [lang])); + + _line('options:-w', 'Process waypoint information'); + _line('options:-r', 'Process route information'); + _line('options:-t', 'Process track information'); + + _line('options:-s', 'Synthesize shortnames'); + _line('options:-c', 'Character set for next operation'); + + + for i := 0 to FCaps.Count - 1 do + begin + if not FCaps.IsFile(i) then Continue; + + s := FCaps.GetDescr(i); + UniWrite(f, Format('format:%s,', [FCaps.GetName(s)])); + UniWriteLn(f, '"' + s + '","' + _translate(GPSBabel_Domain, s) + '"'); + + l := FOpts.FormatOpts(s); + if (l = nil) then Continue; + + for j := 0 to l.Count - 1 do + begin + o := Pointer(l.Objects[j]); + UniWrite(f, Format('format:%s:%s,', [o.format, o.name])); + UniWriteLn(f, '"' + o.hint + '","' + _translate(GPSBabel_Domain, o.hint) + '"'); + end; + end; + + finally + f.Free; + end; + + finally + UseLanguage(curr_lang); + end; +end; + +procedure TfrmMain.cbOutputDeviceChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.cbInputDeviceChange(Sender: TObject); +begin + CheckInput; +end; + +procedure TfrmMain.InitializeSerialPorts; +var + port: string; + i: Integer; + config: TCommConfig; + cfsize: DWORD; +begin + for i := 1 to MAX_NO_OF_SERIAL_PORTS do + begin + port := Format('COM%d', [i]); + cfsize := sizeof(config); + if GetDefaultCommConfig(PChar(port), config, cfsize) then + begin + cbInputDevice.Items.Add(Format('COM%d', [i])); + cbOutputDevice.Items.Add(Format('COM%d', [i])); + end; + end; +end; + +end. diff --git a/win32/gui-2/options.dfm b/win32/gui-2/options.dfm new file mode 100644 index 0000000000000000000000000000000000000000..a30cc841c7182acccbfd3df2c37f37f20866ac77 GIT binary patch literal 1313 zcmb_c%Z}496m`<3&Z9HK0v7Bl!MYl0zMxH~>ZsF6)C6^fz)9WKs$*Aoo&qkNy!JF&!T{s!clgrdMRZY^(>4LB&zf1AG40OSu+dn;hyFmr+oXnD5f>_y0 zuplebuf+zypW=sD;9G+4ywiv-LxGXRQDukg#=Inzb?|h@lU!iTLZw?(B4)mW3QH8` z>_tprjrbjdY7kM>my?*>V_L>oT(Nv(zxS(2>lsf#Cyf!q)ZMWmmy#EHF*eY9`39W5 zrJcH==L{%WGw32}zIRiU>0xaEU^*mHS?*+#MN_lluNum38zej51HFU;H4PVK;GnGv z0Yuw*wM}pY2$f1o@-6f=pgy;!%5B)rw$Zd9^i(}WEXUN4zS6n+FH*}8z-&9nxR4D8 zR2&mbcgCQ0Wzd1(?Lk#Dy?vOzTX!DK-^sQW765zyy&bDFezXAlAOBlwC5Hu=&^w`| z7bEW}68qzEi49^TR0=h(>zhjzb+-|30Vkc|f_p`=K!OprHnPln|FYNh(b^mL8mb&6 zlJDF`p9z?!^%jZ{x)PcA*AM(Or-NLQTWtOwPhr7hAMLT~IY!Hf(Fd>54}t|^a*pK( K!Ae)H8T6~!@ literal 0 HcmV?d00001 diff --git a/win32/gui-2/options.pas b/win32/gui-2/options.pas new file mode 100644 index 000000000..1c30b98c5 --- /dev/null +++ b/win32/gui-2/options.pas @@ -0,0 +1,820 @@ +unit options; + +{ + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +interface + +uses + TypInfo, gnugettext, gnugettextDx, + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, ComCtrls, Buttons, Registry, + Common, delphi; + +type + TfrmOptions = class(TForm) + pnBottom: TPanel; + pnOptions: TPanel; + btnOK: TBitBtn; + btnCancel: TBitBtn; + btnHelp: TBitBtn; + mmWarning: TMemo; + procedure CheckBoxClicked(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure btnHelpClick(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure btnOKClick(Sender: TObject); + private + { Private declarations } + FOpts: TStringList; + FCanvas: TCanvas; + FInitialOpts: string; + procedure CreateStringOption(const x, y, tag: Integer; o: POption; xmax: Integer = -1); + procedure CreateIntegerOption(const x, y, tag: Integer; o: POption; xmax: Integer = -1); + procedure CreateFileOption(const x, y, tag: Integer; o: POption; IsInput: Boolean; xmax: Integer = -1); + function FindUpDown(AControl: TControl): TUpDown; + function GetOptsStr: string; + procedure OptionOpenFile(Sender: TObject); + procedure OptionSaveFile(Sender: TObject); + function ParseOptsLine(const Line: string; List: TStrings): Integer; + procedure SetOpts(AList: TStringList); + procedure SetOptsStr(const AValue: string); + procedure StoreOptionsToInifile(); + procedure StoreOptionsToRegistry(); + procedure LoadSettingsFromRegistry(); + public + { Public declarations } + FFormat: string; + FIsInput: Boolean; + constructor Create(AOwner: TComponent); override; + property + Opts: TStringList read FOpts write SetOpts; + property OptsStr: string read GetOptsStr write SetOptsStr; + end; + +type + eUnknownOption = class(Exception); + eParserError = class(Exception); + +var + frmOptions: TfrmOptions; + +implementation + +uses + utils, main; + +{$R *.DFM} + +// returns "BottomRight" of Controls rect + +function SetCaption(Control: TControl; const ACaption: string): TPoint; +var + s: TStaticText; + auto, info: PPropInfo; + font: TFont; + parentf: Boolean; +begin + Result := Control.BoundsRect.BottomRight; + + info := GetPropInfo(Control, 'Caption'); + if (info = nil) then Exit; + + SetStrProp(Control, 'Caption', ACaption); + + auto := GetPropInfo(Control, 'AutoSize'); + if (auto <> nil) then + begin + SetOrdProp(Control, auto, Integer(True)); + Result := Control.BoundsRect.BottomRight; + Exit; + end; + + info := GetPropInfo(Control, 'Font'); + if (info = nil) then Exit; + + font := Pointer(GetObjectProp(Control, info)); + + info := GetPropInfo(Control, 'ParentFont'); + if (info <> nil) then + parentf := Boolean(GetOrdProp(Control, info)) else + parentf := False; + +// Controls with Caption but without AutoSize +// TCheckBox, TRadioButton + + s := TStaticText.Create(Control.Owner); + try + s.Font := font; + s.ParentFont := parentf; + s.Visible := False; + s.Parent := Control.Parent; + s.BoundsRect := Control.BoundsRect; + s.AutoSize := True; + s.Caption := ACaption; + Control.Width := 18 + s.Width; + if (Control.Height < s.Height) then + Control.Height := s.Height; + Result := Control.BoundsRect.BottomRight; + finally + s.Free; + end; +end; + +{ TfrmOptions } + +constructor TfrmOptions.Create(AOwner: TComponent); // override; +begin + inherited Create(AOwner); + TranslateComponent(Self); + FCanvas := Main.frmMain.stbMain.Canvas; + mmWarning.Lines.Add(_('Be aware, that most options are made for the output side. ')); + mmWarning.Lines.Add(_('Currently we don''t have a flag which tells us which direction is used by the options.')); +end; + +procedure TfrmOptions.SetOpts(AList: TStringList); +var + i, j: Integer; + c: TComponent; + wc: TControl; + o: POption; + chb: TCheckBox; + xy, _xy: TPoint; + xmax: Integer; + lb: TLabel; +begin + if (AList = nil) then Exit; + + FOpts := AList; + + xy.x := 0; + xy.y := 8; + xmax := 0; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + o.chb := nil; + o.edit := nil; + + if (FFormat = '') then + begin + FFormat := o.format; + btnHelp.Hint := readme_html_path + '#' + FFormat; + btnHelp.ShowHint := True; + end; + + if FIsInput and ( + (AnsiPos('generate ', o.hint) <> 0) or + (AnsiPos(' generate', o.hint) <> 0) or + (AnsiPos('output ', o.hint) <> 0) or + (AnsiPos(' output', o.hint) <> 0) or + (AnsiPos('write', o.hint) <> 0) or + (AnsiPos(' write', o.hint) <> 0)) then Continue; + + chb := TCheckBox.Create(nil); + o.chb := chb; + chb.Name := '___' + o.name; + chb.OnClick := CheckBoxClicked; + chb.Tag := i + 1; + + InsertComponent(chb); + + chb.ParentFont := False; + chb.Font := pnOptions.Font; + chb.Left := 8; + chb.Top := xy.y; + _xy := SetCaption(chb, dgettext(GPSBabel_Domain, o.Hint)); + chb.Alignment := taRightJustify; +// chb.Checked := (gpsbabel_ini.ReadString(o.format, o.name, #1) <> #1); + chb.Parent := pnOptions; + + chb.Hint := SysUtils.Format(_('Short "%s"'), [o.name]); + chb.ShowHint := True; + + xy.y := xy.y + chb.Height + 8; + if (o.otype <> 4) then + if (chb.Width > xy.x) then xy.x := chb.Width; + if (chb.Width > xy.x) then + xmax := chb.Width; + + if (o.otype = 4) and (o.def <> nil) and (atoi(o.def) <> 0) then + begin + chb.AllowGrayed := True; + chb.State := cbGrayed; + end; + end; + + xy.y := 8; + xy.X := xy.X + 8; + if (xy.X < 42) then xy.X := 42; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + o.edit := nil; + + if (o.chb = nil) then Continue; + + // ('unknown', 'integer', 'float', 'string', 'boolean', 'file', 'outfile'); + case o.otype of + 1: CreateIntegerOption(xy.X, xy.Y - 2, i + 1, o, xmax); + 2, 3: CreateStringOption(xy.X, xy.Y - 2, i + 1, o, xmax); + 4: ; + 5: // ??? if FIsInput then + CreateFileOption(xy.X, xy.Y - 2, i + 1, o, True, xmax); + 6: if not FIsInput then CreateFileOption(xy.X, xy.Y - 2, i + 1, o, False, xmax); + end; + if (o.edit <> nil) then + o.edit.Enabled := False; + xy.y := xy.y + o.chb.Height + 8; + end; + + xy.X := 0; + xy.Y := 0; + + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if not c.InheritsFrom(TControl) then Continue; + if (c is TPanel) then Continue; + wc := Pointer(c); + if (wc.Parent <> pnOptions) then Continue; + + j := wc.Left + wc.Width; + if (j > xy.X) then xy.X := j; + j := wc.Top + wc.Height; + if (j > xy.Y) then xy.Y := j; + if ( wc.Name = '' ) then Continue; + end; + + Self.Width := xy.X + 8 + (Self.Width - Self.ClientWidth); + Self.Height := xy.Y + 8 + + mmWarning.Height + + pnBottom.Height + + (Self.Height - Self.ClientHeight); + + i := btnCancel.Left - btnOK.Left; + btnCancel.Left := pnBottom.Width - btnCancel.Width - btnHelp.Left; + btnOK.Left := btnCancel.Left - i; + + LoadSettingsFromRegistry(); +end; + +function TfrmOptions.GetOptsStr: string; +var + i: Integer; + o: POption; + c: TComponent; + s: string; +begin + Result := ''; + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + if o.chb.AllowGrayed then + begin + if (o.chb.State = cbGrayed) then Continue + end + else if not(o.chb.Checked) then Continue; + + if (Result <> '') then + Result := Result + ','; + Result := Result + o.name; + + if (o.edit = nil) then + begin + if o.chb.Checked then + Result := Result + '=1' + else + Result := Result + '=0'; + Continue; + end; + s := GetStrProp(o.edit, 'Text'); + if (Pos(' ', s) <> 0) or (Pos('"', s) <> 0) or (Pos(',', s) <> 0) then + s := SysUtils.AnsiQuotedStr(s, '"'); + Result := SysUtils.Format('%s=%s', [Result, s]); + end; +end; + +procedure TfrmOptions.SetOptsStr(const AValue: string); +var + l: TStrings; + i, j: Integer; + s, name, value: string; + o: POption; + ud: TUpDown; +begin + l := TStringList.Create; + try + + try + ParseOptsLine(AValue, l); + except + on E: exception do + raise eParserError.Create(_('Invalid line format!')); + end; + + for i := 0 to l.Count - 1 do + begin + s := l.Strings[i]; + j := Pos('=', s); + if (j > 0) then + begin + name := Copy(s, 1, j - 1); + value := Copy(s, j + 1, Length(s) - j); + end + else + begin + Name := s; + Value := ''; + end; + if (name = '') then Continue; + + j := FOpts.IndexOf(name); + if (j < 0) then + raise eUnknownOption.CreateFmt(_('Unknown option "%s"!'), [name]); + + o := Pointer(FOpts.Objects[j]); + if (o.edit <> nil) then + begin + o.chb.Checked := True; + ud := FindUpDown(o.Edit); + if (ud <> nil) then + ud.Position := StrToInt(Value) + else + SetStrProp(o.edit, 'Text', Value); + end + else if (o.otype = 4) then + o.chb.Checked := (value = '') or (value <> '0'); + end; + finally + l.Free; + end; + FInitialOpts := GetOptsStr; +end; + +procedure TfrmOptions.CheckBoxClicked(Sender: TObject); +var + i: Integer; + c: TComponent; + chb: TCheckBox; + ctrl: TWinControl; +begin + if (Sender = nil) or not (Sender is TCheckBox) then Exit; + chb := Pointer(Sender); + + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if (c = chb) or not(c.InheritsFrom(TWinControl)) then Continue; + if (c.Tag <> chb.Tag) then Continue; + ctrl := Pointer(c); + ctrl.Enabled := chb.Checked; + end; +end; + +procedure TfrmOptions.CreateStringOption(const x, y, tag: Integer; o: POption; xmax: Integer); +var + ed: TEdit; +begin + ed := TEdit.Create(Self); + o.edit := ed; + + ed.Left := x; + ed.Top := y; + ed.Tag := tag; + ed.Parent := pnOptions; + + if (o.def <> nil) then + ed.Text := string(o.def); +end; + +procedure TfrmOptions.CreateIntegerOption(const x, y, tag: Integer; o: POption; xmax: Integer); +var + ed: TEdit; + cb: TComboBox; + up: TUpDown; + i: Integer; +begin + if (o.min <> nil) and (o.max <> nil) and + ((StrToInt(o.max) - StrToInt(o.min)) < 32) then + begin + cb := TComboBox.Create(Self); + o.edit := cb; + cb.Left := x; + cb.Top := y; + cb.Tag := tag; + if (cb.Left + cb.Width < xmax) then + cb.Left := xmax - cb.Width; + cb.Parent := pnOptions; + + for i := StrToInt(o.min) to StrToInt(o.max) do + cb.Items.Add(IntToStr(i)); + if (o.def <> nil) then + cb.Text := o.def + else + cb.ItemIndex := 0; + Exit; + end; + + ed := TEdit.Create(Self); + o.edit := ed; + + ed.Left := x; + ed.Top := y; + ed.Tag := tag; + ed.Parent := pnOptions; + + up := TUpDown.Create(Self); + up.Parent := pnOptions; + + ed.Width := ed.Width - up.Width; + up.Left := ed.Left + ed.Width; + up.Top := ed.Top; + if (o.min <> nil) then + up.Min := StrToInt(o.min) + else + up.Min := -(MAXSHORT-1); + if (o.max <> nil) then + up.Max := StrToInt(o.max) + else + up.Max := MAXSHORT; + if (o.def <> nil) then + up.Position := StrToInt(o.def); + up.Associate := ed; +end; + +procedure TfrmOptions.FormCreate(Sender: TObject); +begin + TranslateComponent(Self); +end; + +procedure TfrmOptions.btnHelpClick(Sender: TObject); +begin + WinOpenURL(readme_html_path + '#fmt_' + FFormat); +end; + +procedure TfrmOptions.CreateFileOption(const x, y, tag: Integer; o: POption; IsInput: Boolean; xmax: Integer = -1); +var + ed: TEdit; + btn: TSpeedButton; +begin + ed := TEdit.Create(Self); + o.edit := ed; + + ed.Left := x; + ed.Top := y; + ed.Tag := tag; + ed.Parent := pnOptions; + + btn := TSpeedButton.Create(Self); + btn.Parent := pnOptions; + btn.Tag := tag; + ed.Width := ed.Width - btn.Width; + btn.Left := ed.Left + ed.Width; + btn.Top := ed.top; + + if IsInput then + begin + btn.OnClick := Self.OptionOpenFile; + frmMain.ImageList1.GetBitmap(15, btn.Glyph); + end + else + begin + btn.OnClick := Self.OptionSaveFile; + frmMain.ImageList1.GetBitmap(17, btn.Glyph); + end; +end; + +procedure TfrmOptions.OptionOpenFile(Sender: TObject); +var + c: TControl; + i: Integer; + o: POption; + d: TOpenDialog; +begin + if (Sender = nil) or not(Sender is TControl) then Exit; + + c := Pointer(Sender); + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) or (o.chb.Tag <> c.Tag) then Continue; + + d := TOpenDialog.Create(Self); + try + d.FileName := GetStrProp(o.edit, 'Text'); + if d.Execute then + SetStrProp(o.edit, 'Text', d.FileName); + finally + d.Free; + end; + end; +end; + +procedure TfrmOptions.OptionSaveFile(Sender: TObject); +var + c: TControl; + i: Integer; + o: POption; + d: TSaveDialog; +begin + if (Sender = nil) or not(Sender is TControl) then Exit; + + c := Pointer(Sender); + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) or (o.chb.Tag <> c.Tag) then Continue; + + d := TSaveDialog.Create(Self); + try + d.FileName := GetStrProp(o.edit, 'Text'); + if d.Execute then + SetStrProp(o.edit, 'Text', d.FileName); + finally + d.Free; + end; + end; +end; + +function TfrmOptions.ParseOptsLine(const Line: string; List: TStrings): Integer; +var + s, name, val: string; + cin, cend: PChar; + c1, c2: PChar; + ins: Boolean; +begin + List.Clear; + s := Trim(line) + ','; + + cin := PChar(s); + cend := cin + StrLen(cin); + + while (cin < cend) do + begin + c1 := StrScan(cin, '='); + c2 := StrScan(cin, ','); + if (c1 > c2) then c1 := nil; + + if (c1 <> nil) then + begin + c1^ := #0; + name := string(cin); + val := ''; + + c1 := c1 + 1; + while (c1^ > #0) and (c1^ <= ' ') do c1 := c1 + 1; + + if (c1^ = '"') then // dequote + begin + while (c1 < cend) do + begin + c1 := c1 + 1; + if (c1^ = '"') then + begin + if ((c1+1)^ = '"') then + c1 := c1 + 1 + else + Break; + end; + val := val + c1^; + end; + c2 := StrScan(c1 + 1, ','); + end + else + begin + c2^ := #0; + val := string(c1); + end; + end + else + begin + c2^ := #0; + name := string(cin); + end; + + if (name <> '') then + begin + if (val <> '') then + list.Add(Format('%s=%s', [name, val])) + else + list.Add(name); + end; + + if (c2 = nil) then + Break + else + cin := c2 + 1; + end; + + Result := List.Count; +end; + +function TfrmOptions.FindUpDown(AControl: TControl): TUpDown; +var + i: Integer; + c: TComponent; +begin + Result := nil; + for i := 0 to ComponentCount - 1 do + begin + c := Components[i]; + if c.InheritsFrom(TUpDown) and (TUpDown(c).Associate = AControl) then + begin + Result := Pointer(c); + Exit; + end; + end; +end; + +procedure TfrmOptions.FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +var + str: string; +begin + if (Key <> 27) then Exit; + + str := GetOptsStr; + if (str <> FInitialOpts) then + begin + if not(MessageDlg(_('Discard changes?'), mtWarning, mbOKCancel, 0) = mrOK) then + Exit; + end; + ModalResult := mrCancel; +end; + +procedure TfrmOptions.StoreOptionsToInifile(); +var + i: Integer; + o: POption; + c: TComponent; + s, value: string; +begin +(* + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + if o.chb.AllowGrayed then + begin + if (o.chb.State = cbGrayed) then + begin + gpsbabel_ini.DeleteKey(o.format, o.name); + Continue; + end; + end + else if not(o.chb.Checked) then + begin + gpsbabel_ini.DeleteKey(o.format, o.name); + Continue; + end; + + if (o.edit = nil) then + begin + if o.chb.Checked then + value := '1' + else + value := '0'; + end + else value := GetStrProp(o.edit, 'Text'); + if (o.gbdef <> nil) and (StrPas(o.gbdef) = value) then + gpsbabel_ini.DeleteKey(o.format, o.name) + else + gpsbabel_ini.WriteString(o.format, o.name, value); + end; +*) +end; + +procedure TfrmOptions.StoreOptionsToRegistry(); +var + i: Integer; + o: POption; + c: TComponent; + s, key, value: string; + r: TRegistry; +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKey('\Software\GPSBabel', True)) then Exit; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + key := o.format + ':' + o.name; + + if o.chb.AllowGrayed then + begin + if (o.chb.State = cbGrayed) then + begin + r.DeleteValue(key); + Continue; + end; + end + else if not(o.chb.Checked) then + begin + r.DeleteValue(key); + Continue; + end; + + if (o.edit = nil) then + begin + if o.chb.Checked then + value := '1' + else + value := '0'; + end + else value := GetStrProp(o.edit, 'Text'); + if (o.gbdef <> nil) and (StrPas(o.gbdef) = value) then + r.WriteString(key, '(default)') + else + r.WriteString(key, value); + end; + finally + r.Free; + end; +end; + +procedure TfrmOptions.LoadSettingsFromRegistry(); +var + i: Integer; + o: POption; + c: TComponent; + s, key, value: string; + r: TRegistry; + u: TUpDown; +begin + r := TRegistry.Create; + try + r.RootKey := HKEY_CURRENT_USER; + if not(r.OpenKeyReadOnly('\Software\GPSBabel')) then Exit; + + for i := 0 to FOpts.Count - 1 do + begin + o := Pointer(FOpts.Objects[i]); + if (o.chb = nil) then Continue; + + key := o.format + ':' + o.name; + if not r.ValueExists(key) then Continue; + + Value := r.ReadString(key); + if (o.edit = nil) then + begin + if o.chb.AllowGrayed then + begin + if (value = '1') then + o.chb.State := cbChecked + else + o.chb.State := cbUnChecked; + end + else o.chb.Checked := True; + end + else + begin + o.chb.Checked := True; + if (value <> '(default)') then + begin + if HasUpDown(TEdit(o.edit), u) then + u.Position := StrToInt(value) + else + SetStrProp(o.edit, 'Text', value); + end; + o.edit.Enabled := True; + end; + end; + finally + r.Free; + end; +end; + +procedure TfrmOptions.btnOKClick(Sender: TObject); +begin +//StoreOptionsToInifile(); + StoreOptionsToRegistry(); +end; + +end. diff --git a/win32/gui-2/readme.dfm b/win32/gui-2/readme.dfm new file mode 100644 index 0000000000000000000000000000000000000000..3036ad2a07926f655b66e75feb1d84e4a9a5c2e1 GIT binary patch literal 687 zcmYLH!H(K65Oop~CjoYQ=w)w6y;u7SBtW-f*+j(c-r720SS%bHIbK*kpkGm`pVL3; zxpm?QE|zD;esAWz`4=OySg+Re>1;Je_wRnW2$6hoACs-B*FZNlM3>v(5w_a<=6FON zygSE#W*fcp-n+pAu$P_o{x~?L2hF4iZa?KkLQCKi3+<HDK3PF62i?)?>Y`Rw z7xk)+E~@@?{3&NI0*92RoSE)=F@uV)K)i;nO_|{5C^iE~&J&|4j+^EyD9tL$Lqf}L zTH`GWNKOUt@E{VYwX8c&Ew^Wwtfd!n_rsOjzK;_)0?%HJL^vpqPg1}Y-$9rpOdE^+ zQj2V97v^`jFfO*>?!I3a_YO~uE>bl^pYF}f#j5M7%O8wf45m*f_yJ@gc{@`aotaG;3-0fDO=+r=!wV(}ug`MO0ys<@%3 zQq>>RLw-pQRn)E$&X4Y?3EVIO`wHuvkz3O`8ZQ*N*5U*8x zoAvt9sKYq(WoGRq>#Q#mUyOt&#)*QFFZ(h$XRZikB)Dbst`5jmMATzZM_zGe+1<&0 zK)E>GaCyK&dBB3xflQ>0oL-*AH6pKa72?~Xg5(S%9s`F^!l z{!sTmx(DTUr|M<(u8P_4`AHD=#D&K$WlnAAD(0VzS{>67OXnM%?G6nm+Z`4KeI2ik zm?O`cyyr%YO4h`K+jcY5OABbxNc-t#*cpfm%SH&jd@HzQe9~gkVdxLcPgyJ<7tWKk z*PTIeD zrV(fRY^<{VdXz1e*7o^f*cX-I|4?@EG-b1gl8s_b3fUHo;09nz?1x`SR$|%Xup*=s zqX&8=K%IXCGq>;c(){~u2C=+KAmI+Bx-x7Y=_~tPOP|!4Oh4Aj+_K8hIuT8BDLRDa zSajIN>j|Q-8<0GLyJaQ2!{!lLC(l4~mxey$y1*;lji(n#>*$Q-(yNwYrNwwUIa@dm;0oK+ zcxf?r_5fE{ae7nSbez(nw77HTh&cchHRjBxu!Goc5eDQ0O388V6c30KdCmp94D(j@S*J4~ZppM2+EhVBxtlox`MJUm_Q=J4IAA lV7a>mQwj4erz;E)JxViumeo3b6OuVT8>yyGO!yZd '') then + begin + i := frmSelect.lbSelect.Items.IndexOf(str); + if (i >= 0) then + frmSelect.lbSelect.ItemIndex := i; + end; + res := frmSelect.ShowModal; + Result := (res = mrOk); + i := frmSelect.lbSelect.ItemIndex; + if Result and (i >= 0) then + Str := frmSelect.lbSelect.Items[i]; + finally + frmSelect.Release; + end; +end; + +function SelectLanguage(const Title: string; const Builtin: TStrings; var Lang: string; const Default: string = ''): Boolean; +var + i: Integer; + s, sx, sy: string; + l: TStrings; + +begin + Result := False; + + if (Default = '') then + Lang := Copy(gnugettext.GetCurrentLanguage, 1, 2); + + l := TStringList.Create; + try + sy := ''; + for i := 0 to Builtin.Count - 1 do + begin + s := Builtin.Strings[i]; + if (s = '') then Continue; + + if (CompareText(s, 'de') = 0) then sx := _('German') else + if (CompareText(s, 'es') = 0) then sx := _('Spanish') else + if (CompareText(s, 'fr') = 0) then sx := _('French') else + if (CompareText(s, 'en') = 0) then sx := _('English') else + sx := '???'; + + sx := Format('%s - %s', [s, sx]); + if (CompareText(s, Lang) = 0) then sy := sx; + + l.Add(sx); + end; + + if SelectFromStringList(Title, l, sy) then + begin + Lang := Copy(sy, 1, 2); + Result := True; + end; + + finally + l.Free; + end; +end; + +{ TfrmSelect } + +procedure TfrmSelect.FormCreate(Sender: TObject); +begin + TranslateComponent(Self); + +// !!! work-arround !!! + btnOK.Caption := dgettext('delphi', 'OK'); + btnCancel.Caption := dgettext('delphi', 'Abort'); +// !!! work-arround !!! +end; + +procedure TfrmSelect.FormShow(Sender: TObject); +var + i: Integer; + s: string; + t: TLabel; +begin + t := TLabel.Create(Self); + try + + t.Caption := ''; + t.Font := lbSelect.Font; + t.ParentFont := lbSelect.ParentFont; + t.Parent := lbSelect.Parent; + + for i := 0 to lbSelect.Items.Count - 1 do + begin + s := Copy(lbSelect.Items[i], 1, 4); + while (t.Canvas.TextWidth(s) < 32) do + s := s + ' '; + s := s + Copy(lbSelect.Items[i], 5, 256); + lbSelect.Items[i] := s; + end; + + finally + t.Free; + end; +end; + +end. diff --git a/win32/gui-2/utils.pas b/win32/gui-2/utils.pas new file mode 100644 index 000000000..8dbb57f74 --- /dev/null +++ b/win32/gui-2/utils.pas @@ -0,0 +1,442 @@ +unit utils; + +{ + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +} + +{ + function gpsbabel created from old gui GPSBabelGUIDialogU.pas +} + +interface + +uses + gnugettext, + Windows, SysUtils, Classes, StdCtrls, ComCtrls, + Registry, ShellAPI; + +type + PBoolean = ^Boolean; + +function gpsbabel(const CommandLine: string; Output: TStrings; + Fatal: PBoolean = nil; OEMStrings: Boolean = True): Boolean; + +function GetShortName(const PathName: string): string; +procedure StoreProfile(const Tag: Integer; const Value: string); +function ReadProfile(const Tag: Integer; const Default: string = ''): string; overload; +function ReadProfile(const Name: string; const Default: string = ''): string; overload; + +function BackupProperties(Instance: TObject; Properties: TStrings; Backup: TStringList): Boolean; +procedure RestoreProperties(Instance: TObject; Backup: TStringList); + +procedure FixStaticText(AComponent: TComponent); + +function WinOpenFile(const AFile, AParams: string): Boolean; +procedure WinOpenURL(const AURL: string); + +procedure UniWrite(Target: TStream; const Str: WideString); +procedure UniWriteLn(Target: TStream; const Str: WideString); + +procedure MakeFirstTranslation(AComponent: TComponent); + +function readme_html_path: string; + +function HasUpDown(E: TEdit; var UpDown: TUpdown): Boolean; + +implementation + +uses + Forms, + common; + +function GetShortName(const PathName: string): string; +var + buffer: array[0..4095] of Char; + len: DWORD; +begin + len := Windows.GetShortPathName(PChar(PathName), @buffer, sizeof(buffer)); + SetString(Result, buffer, len); +end; + +function gpsbabel(const CommandLine: string; Output: TStrings; + Fatal: PBoolean; OEMStrings: Boolean): Boolean; + +// bigger buffer_size speeds up conversion to screen + +const + BUFFER_SIZE = $20000; + +var + hRead, hWrite: THandle; + ProcessInfo: TProcessInformation; + SecurityAttr: TSecurityAttributes; + StartupInfo: TStartupInfo; + sCmd: string; + + BytesRead, BytesDone: DWORD; + buffer_string: string; + buffer: PChar; + Error: DWORD; + Wait_Result: DWORD; + s: string; + i: Integer; + +begin + Result := False; + + // strings are released automatical + // so we don't need a try/finally construct for our read buffer + + SetLength(buffer_string, BUFFER_SIZE); + buffer := PChar(buffer_string); + + if (Fatal <> nil) then Fatal^ := False; + + if (Copy(CommandLine, 1, 1) = '~') then + sCmd := System.Copy(CommandLine, 2, Length(CommandLine) - 1) + else + sCmd := SysUtils.Format('%s %s ', [gpsbabel_exe, CommandLine]); + + SecurityAttr.nLength := sizeof(TSECURITYATTRIBUTES); + SecurityAttr.bInheritHandle := true; + SecurityAttr.lpSecurityDescriptor := nil; + + if not CreatePipe(hRead, hWrite, @SecurityAttr, $8000) then + raise eGPSBabelError.Create(_('Error WINAPI: Could not create "NamedPipe"!')); + + try + + if not FileExists(gpsbabel_exe) then + raise eGPSBabelError.Create(_('"gpsbabel.exe" not found!!!')); + + FillChar (StartupInfo, Sizeof (StartupInfo), #0); + + StartupInfo.cb := Sizeof (StartupInfo); + StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; + StartupInfo.wShowWindow := {SW_HIDE or} SW_SHOWMINNOACTIVE; + StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE); + StartupInfo.hStdOutput:= hWrite; + StartupInfo.hStdError := hWrite; + + FillChar(ProcessInfo, SizeOf(ProcessInfo), #0); + + if not CreateProcess(nil, + pchar(sCmd), nil, nil, true, CREATE_NEW_CONSOLE, // dwCreationFlags, // creation flags + nil, nil, StartupInfo, ProcessInfo) then + begin + Error := GetLastError; + raise eGPSBabelError.CreateFmt( + _('Could not run "gpsbabel.exe" (Error %d)!'), [Error]); + end; + + s := ''; + Error := 0; + + repeat + Wait_Result := WaitforSingleObject(ProcessInfo.hProcess, 10); + if PeekNamedPipe(hRead, nil, 0, nil, @BytesRead, nil) then + begin + if (BytesRead > 0) then + Application.ProcessMessages; + while (BytesRead > 0) do + begin + BytesDone := BytesRead; + if (BytesDone > (BUFFER_SIZE - 1)) then BytesDone := BUFFER_SIZE - 1; + ReadFile(hRead, buffer^, BytesDone, BytesDone, nil); + if (BytesDone > 0) then + begin + buffer[BytesDone] := #0; + if OEMStrings then + OemToCharBuff(buffer, buffer, BytesDone); + s := s + string(buffer); + Dec(BytesRead, BytesDone); + end; + end + end; + until (Wait_Result = WAIT_OBJECT_0); + + if (Error = 0) then + if not GetExitCodeProcess(ProcessInfo.hProcess, Error) then Error := 0; + + if (Error <> 0) and (Error <> 1) then + raise eGPSBabelError.CreateFmt(_('"gpsbabel.exe" returned error 0x%x (%d)'), [Error, Error]); + + Output.Clear; + while True do + begin + i := Pos(#13#13, s); + if (i <> 0) then System.Delete(s, i, 1) + else break; + end; + Output.SetText(PChar(s)); + + Result := True; + if (Fatal <> nil) then + Fatal^ := (Error = 1); + + finally + CloseHandle (hRead); + CloseHandle (hWrite); + end; +end; + +procedure StoreProfile(const Tag: Integer; const Value: string); +var + reg: TRegistry; + str: string; +begin + if (Tag <= 0) or (Tag > High(Profile)) then Exit; + + str := Profile[Tag]; + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.OpenKey('\SOFTWARE\GPSBabel', True) then + begin + reg.WriteString(str, Value); + end; + finally + reg.Free; + end; +end; + +function ReadProfile(const Tag: Integer; const Default: string): string; // overload; +var + str: string; +begin + if (Tag <= 0) or (Tag > High(Profile)) then Exit; + str := Profile[Tag]; + Result := ReadProfile(str, Default); +end; + +function ReadProfile(const Name: string; const Default: string = ''): string; // overload; +var + reg: TRegistry; +begin + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.OpenKey('\SOFTWARE\GPSBabel', True) then + begin + try + Result := reg.ReadString(Name); + except + Result := Default; + end; + end; + finally + reg.Free; + end; +end; + +function BackupProperties(Instance: TObject; Properties: TStrings; Backup: TStringList): Boolean; +var + List: TStringList; +begin + List := TStringList.Create; + try + Backup.Assign(List); + finally + List.Free; + end; +end; + +procedure RestoreProperties(Instance: TObject; Backup: TStringList); +begin +end; + +procedure FixStaticText(AComponent: TComponent); +var + i, j: Integer; + c: TComponent; + s: TStaticText; +begin + j := AComponent.ComponentCount; + for i := 0 to j - 1 do + begin + c := AComponent.Components[i]; + if (c.ComponentCount > 0) then FixStaticText(c); + + if not c.InheritsFrom(TStaticText) then Continue; + + s := c as TStaticText; + if (s.BorderStyle = sbsNone) then Continue; + + if (s.Alignment = taLeftJustify) then + s.Caption := ' ' + s.Caption + else if (s.Alignment = taRightJustify) then + s.Caption := s.Caption + ' '; + end; +end; + +function WinOpenFile(const AFile, AParams: string): Boolean; +var + p: PChar; +begin + if (AParams = '') then + p := nil else + p := PChar(AParams); + Result := (ShellExecute(0, 'open', PChar(AFile), p, nil, SW_SHOW) > 32); +end; + +procedure WinOpenURL(const AURL: string); +var + i: Integer; + reg: TRegistry; + cmd: string; + prg: string; + url: string; +begin + url := AURL; + reg := TRegistry.Create; + try + reg.RootKey := HKEY_LOCAL_MACHINE; + if reg.OpenKeyReadOnly('Software\Classes\HTTP\Shell\Open\Command') then + begin + prg := reg.ReadString(''); + if (prg <> '') then + begin + i := Pos('%1', prg); + if (i <> 0) then + begin + System.Delete(prg, i, 2); + System.Insert(url, prg, i); + url := ''; + end; + + if (prg[1] = '"') then + begin + i := Pos('"', Copy(prg, 2, Length(prg))); + if (i = 0) then Exit; + cmd := Copy(prg, 2, i - 1); + Delete(prg, 1, i + 1); + prg := Trim(prg); + if (url <> '') then + begin + if (prg = '') then + prg := URL else + prg := prg + ' ' + URL; + end; + if WinOpenFile(cmd, PChar(prg)) then Exit + end + else + if (Pos(' ', prg) <> 0) then + begin + i := Pos(' ', prg); + cmd := Trim(Copy(prg, 1, i - 1)); + prg := Trim(Copy(prg, i + 1, Length(prg))); + if (url <> '') then + begin + if (prg = '') then + prg := URL + else + prg := Trim(prg) + ' ' + URL; + end; + if WinOpenFile(cmd, PChar(prg)) then Exit; + end + else + if WinOpenFile(prg, PChar(URL)) then Exit; + end; + end; + finally + reg.Free; + end; + WinOpenFile(AURL, ''); +end; + +procedure UniWrite(Target: TStream; const Str: WideString); +const + UniHeader: array[0..1] of Byte = ($FF, $FE); +var + len: Integer; +begin + if (Target.Size = 0) then Target.Write(UniHeader, SizeOf(UniHeader)); + len := Length(Str); + if (len > 0) then + Target.Write(PWideChar(Str)^, len * 2); +end; + +procedure UniWriteLn(Target: TStream; const Str: WideString); +begin + UniWrite(Target, Str); + UniWrite(Target, #13#10); +end; + +procedure MakeFirstTranslation(AComponent: TComponent); +var + lang: string; +begin +// !!! TRICK !!! + lang := GetCurrentLanguage; + UseLanguage('en'); + TranslateComponent(AComponent); + if (Copy(lang, 1, 2) <> 'en') then + begin + UseLanguage(lang); + ReTranslateComponent(AComponent); + end; +// !!! TRICK !!! +end; + +function readme_html_path: string; +begin + Result := ExtractFilePath(ParamStr(0)) + 'gpsbabel.html'; + if FileExists(Result) then + begin + while (Pos('\', Result) <> 0) do + Result[Pos('\', Result)] := '/'; + Result := 'file:///' + Result; + end + else + Result := SGPSBabelURL + '/gpsbabel.html'; +end; + +function HasUpDown(E: TEdit; var UpDown: TUpdown): Boolean; +var + i: Integer; + c: TComponent; + o: TComponent; +begin + Result := False; + o := E.Owner; + for i := 0 to o.ComponentCount - 1 do + begin + c := o.Components[i]; + if (c is TUpDown) and (TUpDown(c).Associate = E) then + begin + UpDown := TUpDown(c); + Result := True; + Exit; + end; + end; +end; + + +var + hMutex: THandle; + +initialization + + // Flag for InnoSetup + hMutex := CreateMutex(nil, True, 'GPSBabelGUI_mutex'); + +finalization + + if (hMutex <> 0) then + CloseHandle(hMutex); + +end. diff --git a/xcsv.c b/xcsv.c index 48acccd89..6c246c4c5 100644 --- a/xcsv.c +++ b/xcsv.c @@ -27,6 +27,7 @@ #include "defs.h" #include "csv_util.h" +#if CSVFMTS_ENABLED #define MYNAME "XCSV" #define ISSTOKEN(a,b) (strncmp(a,b, strlen(b)) == 0) @@ -43,21 +44,21 @@ static const char *intstylebuf = NULL; static arglist_t xcsv_args[] = { {"style", &styleopt, "Full path to XCSV style file", NULL, - ARGTYPE_FILE | ARGTYPE_REQUIRED }, + ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, {"snlen", &snlenopt, "Max synthesized shortname length", NULL, - ARGTYPE_INT}, - {"snwhite", &snwhiteopt, "(0/1) Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL}, - {"snupper", &snupperopt, "(0/1) UPPERCASE synth. shortnames", - NULL, ARGTYPE_BOOL}, - {"snunique", &snuniqueopt, "(0/1) Make synth. shortnames unique", - NULL, ARGTYPE_BOOL}, + ARGTYPE_INT, "1", NULL}, + {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + {"snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, {"urlbase", &xcsv_urlbase, "Basename prepended to URL on output", - NULL, ARGTYPE_STRING}, + NULL, ARGTYPE_STRING, ARG_NOMINMAX}, {"prefer_shortnames", &prefer_shortnames, "Use shortname instead of description", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; /* a table of config file constants mapped to chars */ @@ -159,7 +160,7 @@ xcsv_destroy_style(void) xfree(xcsv_file.extension); if (xcsv_file.mkshort_handle) - xfree(xcsv_file.mkshort_handle); + mkshort_del_handle(&xcsv_file.mkshort_handle); /* return everything to zeros */ internal = xcsv_file.is_internal; @@ -217,15 +218,13 @@ xcsv_parse_style_line(const char *sbuff) p = csv_stringtrim(xcsv_file.field_delimiter, " ", 0); /* field delimiters are always bad characters */ - if (xcsv_file.badchars) { - xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, - strlen(xcsv_file.badchars) + - strlen(p) + 1); + if (0 == strcmp(p, "\\w")) { + char *s = xstrappend(xcsv_file.badchars, " \n\r"); + if (xcsv_file.badchars) xfree(xcsv_file.badchars); + xcsv_file.badchars = s; } else { - xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + xcsv_file.badchars = xstrappend(xcsv_file.badchars, p); } - - strcat(xcsv_file.badchars, p); xfree(p); @@ -323,6 +322,12 @@ xcsv_parse_style_line(const char *sbuff) xcsv_epilogue_add(xstrdup(&sbuff[9])); } else + if (ISSTOKEN(sbuff, "ENCODING")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + cet_convert_init(p, 1); + xfree(p); + } else + if (ISSTOKEN(sbuff, "IFIELD")) { key = val = pfc = NULL; @@ -361,6 +366,7 @@ xcsv_parse_style_line(const char *sbuff) * change the world on ifield vs ofield format later.. */ if (ISSTOKEN(sbuff, "OFIELD")) { + int options = 0; key = val = pfc = NULL; s = csv_lineparse(&sbuff[6], ",", "", linecount); @@ -380,6 +386,17 @@ xcsv_parse_style_line(const char *sbuff) /* printf conversion */ pfc = csv_stringtrim(s, "\"", 1); break; + case 3: + /* Any additional options. */ + if (strstr(s, "no_delim_before")) { + options |= OPTIONS_NODELIM; + } + if (strstr(s, "absolute")) { + options |= OPTIONS_ABSOLUTE; + } + if (strstr(s, "optional")) { + options |= OPTIONS_OPTIONAL; + } default: break; } @@ -387,7 +404,7 @@ xcsv_parse_style_line(const char *sbuff) s = csv_lineparse(NULL, ",", "", linecount); } - xcsv_ofield_add(key, val, pfc); + xcsv_ofield_add(key, val, pfc, options); } } } @@ -421,19 +438,17 @@ xcsv_parse_style_buff(const char *sbuff) static void xcsv_read_style(const char *fname) { - char sbuff[8192]; - FILE *fp; + char *sbuff; + gbfile *fp; xcsv_file_init(); - fp = xfopen(fname, "r", MYNAME); + fp = gbfopen(fname, "rb", MYNAME); - do { - memset(sbuff, '\0', sizeof(sbuff)); - fgets(sbuff, sizeof(sbuff), fp); - rtrim(sbuff); + while ((sbuff = gbfgetstr(fp))) { + sbuff = lrtrim(sbuff); xcsv_parse_style_line(sbuff); - } while (!feof(fp)); + } while (!gbfeof(fp)); /* if we have no output fields, use input fields as output fields */ if (xcsv_file.ofield_ct == 0) { @@ -442,8 +457,7 @@ xcsv_read_style(const char *fname) xcsv_file.ofield = &xcsv_file.ifield; xcsv_file.ofield_ct = xcsv_file.ifield_ct; } - - fclose(fp); + gbfclose(fp); } /* @@ -500,14 +514,14 @@ xcsv_rd_init(const char *fname) warning(MYNAME " attempt to read %s as a track or route, but this module only supports waypoints on read. Reading as waypoints instead.\n", fname); } - xcsv_file.xcsvfp = xfopen(fname, "r", MYNAME); + xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME); } static void xcsv_rd_deinit(void) { - fclose(xcsv_file.xcsvfp); + gbfclose(xcsv_file.xcsvfp); xcsv_destroy_style(); } @@ -529,7 +543,7 @@ xcsv_wr_init(const char *fname) xcsv_read_style(styleopt); } - xcsv_file.xcsvfp = xfopen(fname, "w", MYNAME); + xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME); xcsv_file.fname = (char *)fname; /* set mkshort options from the command line */ @@ -556,7 +570,7 @@ xcsv_wr_init(const char *fname) static void xcsv_wr_deinit(void) { - fclose(xcsv_file.xcsvfp); + gbfclose(xcsv_file.xcsvfp); xcsv_destroy_style(); } @@ -571,5 +585,10 @@ ff_vecs_t xcsv_vecs = { xcsv_data_read, xcsv_data_write, NULL, - xcsv_args + xcsv_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#else +void xcsv_read_internal_style(const char *style_buf) {} +void xcsv_setup_internal_style(const char *style_buf) {} +#endif //CSVFMTS_ENABLED diff --git a/xmldoc/babelmain.xsl b/xmldoc/babelmain.xsl new file mode 100644 index 000000000..1bcac1910 --- /dev/null +++ b/xmldoc/babelmain.xsl @@ -0,0 +1,35 @@ + + + + + +http://www.gpsbabel.org/style3.css +1 +1 +1 + + + + + + #include virtual="../navbar.inc" + #include virtual="../doc-header.inc" + + + + + + + + + + #include virtual="../doc-footer.inc" + + + + + + diff --git a/xmldoc/chapters/_chapters.xml b/xmldoc/chapters/_chapters.xml new file mode 100644 index 000000000..c708c6b05 --- /dev/null +++ b/xmldoc/chapters/_chapters.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/xmldoc/chapters/allchapters.xml b/xmldoc/chapters/allchapters.xml new file mode 100644 index 000000000..82a129bd5 --- /dev/null +++ b/xmldoc/chapters/allchapters.xml @@ -0,0 +1,8 @@ +&chap_preface; +&chap_build; +&chap_use; +&chap_formats; +&chap_filters; +&app_datums; +&app_garmin_icons; +&app_styles; diff --git a/xmldoc/chapters/build.xml b/xmldoc/chapters/build.xml new file mode 100644 index 000000000..a4b2efb3f --- /dev/null +++ b/xmldoc/chapters/build.xml @@ -0,0 +1,58 @@ + + Getting it and Building it + +GPSBabel is distributed "ready to run" on most common +operating systems via the +download page. + + As GPSBabel runs on a wide variety of operating systems, +be sure to visit the +OS-Specific notes for +additional information. + + + For operating systems where no binary is provided or if +you want the latest development version, you will have to build it from +source. The code should be compilable on any system with +ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, +Linux, Solaris, and a variety of processors and compilers. + + + In most cases, the code is as simple to build as running: + ./configure && make + + Expat +is strongly recommended for source builds as it is +required for reading all the XML formats such as GPX. + + libusb +is recommended for OS/X and Linux if you want to use a USB Garmin. + +There are additional flags that can be passed to configure to + customize your build of GPSBabel. ./configure --help lists all the supported options, but additionally we have: + + + Excludes the shapefile support. + + + Excludes the Palm database support and all formats that rely on it. + + + Excludes all support for our something-separated formats. + + + Excludes all filter support. + + + Activate debugging mode for gpsbabel-debug. + + + Specify that the doc should be created and installed in . + + + Disables use of libusb, even it's it's available. + + + By default, we use our own version of zlib. If you specify the system zlib is used. A value of (or --without-zlib) disables zlib. + + diff --git a/xmldoc/chapters/datums.xml b/xmldoc/chapters/datums.xml new file mode 100644 index 000000000..3bc474445 --- /dev/null +++ b/xmldoc/chapters/datums.xml @@ -0,0 +1,138 @@ + +Supported Datums + +Some formats in GPSBabel support multiple datums. For example, the + option to the +garmin_txt format allows you to specify +a datum for the output file. + + +The following is a list of the datums supported by GPSBabel. + + + +Adindan +AFG +Ain-El-Abd +Alaska-NAD27 +Alaska-Canada +Anna-1-Astro +ARC 1950 Mean +ARC 1960 Mean +Asc Island 58 +Astro B4 +Astro Beacon E +Astro pos 71/4 +Astro stn 52 +Australia Geo 1984 +Bahamas NAD27 +Bellevue IGN +Bermuda 1957 +Bukit Rimpah +Camp_Area_Astro +Campo_Inchauspe +Canada_Mean(NAD27) +Canal_Zone_(NAD27) +Canton_Island_1966 +Cape +Cape_Canaveral_mean +Carribean NAD27 +Carthage +Cent America NAD27 +Chatham 1971 +Chua Astro +Corrego Alegre +Cuba NAD27 +Cyprus +Djakarta(Batavia) +DOS 1968 +Easter lsland 1967 +Egypt +European 1950 +European 1950 mean +European 1979 mean +Finnish Nautical +Gandajika Base +Geodetic Datum 49 +Ghana +Greenland NAD27 +Guam 1963 +Gunung Segara +Gunung Serindung 1962 +GUX1 Astro +Herat North +Hjorsey 1955 +Hong Kong 1963 +Hu-Tzu-Shan +Indian +Iran +Ireland 1965 +ISTS 073 Astro 69 +Johnston Island 61 +Kandawala +Kerguelen Island +Kertau 48 +L.C. 5 Astro +La Reunion +Liberia 1964 +Luzon +Mahe 1971 +Marco Astro +Masirah Is. Nahrwan +Massawa +Merchich +Mexico NAD27 +Midway Astro 61 +Mindanao +Minna +Montjong Lowe +Nahrwan +Naparima BWI +North America 83 +N. America 1927 mean +Observatorio 1966 +Old Egyptian +Old Hawaiian_mean +Old Hawaiian Kauai +Old Hawaiian Maui +Old Hawaiian Oahu +Oman +OSGB36 +Pico De Las Nieves +Pitcairn Astro 67 +S. Am. 1956 mean(P) +S. Chilean 1963 (P) +Puerto Rico +Pulkovo 1942 +Qornoq +Quatar National +Rome 1940 +S-42(Pulkovo1942) +S.E.Asia_(Indian) +SAD-69/Brazil +Santa Braz +Santo (DOS) +Sapper Hill 43 +Schwarzeck +Sicily +Sierra Leone 1960 +S. Am. 1969 mean +South Asia +Southeast Base +Southwest Base +Tananarive Obs 25 +Thai/Viet (Indian) +Timbalai 1948 +Tokyo mean +Tristan Astro 1968 +United Arab Emirates +Viti Levu 1916 +Wake Eniwetok 60 +WGS 72 +WGS 84 +Yacare +Zanderij +Sweden + + + diff --git a/xmldoc/chapters/filters.xml b/xmldoc/chapters/filters.xml new file mode 100644 index 000000000..e5b18c8da --- /dev/null +++ b/xmldoc/chapters/filters.xml @@ -0,0 +1,23 @@ + + Data Filters + GPSBabel supports data filtering. Data filters are + invoked from the command line via the '-x' option. It should be + noted that data filters are invoked in the internal pipeline at + the point that corresponds to their position on the + command. This implies that specifying a filter before reading + any data ('-x <filter> -f <file>'), despite being + legal, will not have any effect. The advantage is that filters + can be used intermittently between several variations of input + and output functions. It should also be noted that filtering + data from different input types can sometimes produce + undesirable results due to differences in the native data + formats. + + Beware that most filters only apply to a certain kind of + data. This is usually indicated below by referring to points, + tracks or routes in the first sentence which describes each + filter or in the table at gpsbabel.org + . + + &filters; + diff --git a/xmldoc/chapters/formats.xml b/xmldoc/chapters/formats.xml new file mode 100644 index 000000000..a06e0be6b --- /dev/null +++ b/xmldoc/chapters/formats.xml @@ -0,0 +1,4 @@ + + The Formats + &formats; + diff --git a/xmldoc/chapters/garmin_icons.xml b/xmldoc/chapters/garmin_icons.xml new file mode 100644 index 000000000..8c93e6393 --- /dev/null +++ b/xmldoc/chapters/garmin_icons.xml @@ -0,0 +1,283 @@ + +Garmin Icons + +Following is a list of the valid values for the +garmin option. +These values are also used internally by the +GDB, +BCR, +Mapsource, +Geoniche, +GPilotS, +PCX, and +PSITrex +formats. + + + +Airport +Amusement Park +Anchor Prohibited +Asian Food +Ball Park +Bank +Bar +Beach +Beacon +Bell +Bike Trail +Blue Circle +Blue Diamond +Blue Letter A +Blue Letter B +Blue Letter C +Blue Letter D +Blue Number 0 +Blue Number 1 +Blue Number 2 +Blue Number 3 +Blue Number 4 +Blue Number 5 +Blue Number 6 +Blue Number 7 +Blue Number 8 +Blue Number 9 +Blue Oval +Blue Rectangle +Blue Square +Blue Triangle +Boat Ramp +Border Crossing (Port Of Entry) +Bottom Conditions +Bowling +Bridge +Building +Campground +Car +Car Rental +Car Repair +Cemetery +Church +Circle with X +City (Capitol) +City (Large) +City (Medium) +City (Small) +Civil +Coast Guard +Contact, Afro +Contact, Alien +Contact, Ball Cap +Contact, Big Ears +Contact, Biker +Contact, Bug +Contact, Cat +Contact, Dog +Contact, Dreadlocks +Contact, Female1 +Contact, Female2 +Contact, Female3 +Contact, Goatee +Contact, Kung-Fu +Contact, Pig +Contact, Pirate +Contact, Ranger +Contact, Smiley +Contact, Spike +Contact, Sumo +Controlled Area +Convenience Store +Crossing +Dam +Danger Area +Deli +Department Store +Diamond, Blue +Diamond, Green +Diamond, Red +Diver Down Flag 1 +Diver Down Flag 2 +Dock +Drinking Water +Dropoff +Elevation point +Event Cache +Exit +Exit without services +Fast Food +First approach fix +Fishing Area +Fishing Hot Spot Facility +Fitness Center +Flag +Flag, Blue +Flag, Green +Flag, Red +Forest +Gambling/casino +Gas Station +Geocache +Geocache Found +Geographic place name, land +Geographic place name, Man-made +Geographic place name, water +Ghost Town +Glider Area +Golf Course +Green circle +Green Diamond +Green Letter A +Green Letter B +Green Letter C +Green Letter D +Green Number 0 +Green Number 1 +Green Number 2 +Green Number 3 +Green Number 4 +Green Number 5 +Green Number 6 +Green Number 7 +Green Number 8 +Green Number 9 +Green Oval +Green Rectangle +Green Square +Green Triangle +Heliport +Horn +Hotel +House +Hunting Area +Ice Skating +Information +Intersection +Intl freeway hwy +Intl national hwy +Italian food +Large exit without services +Large Ramp intersection +Levee +Light +Live Theater +Localizer Outer Marker +Locationless (Reverse) Cache +Lodging +Man Overboard +Marina +Medical Facility +Micro-Cache +Mile Marker +Military +Mine +Missed approach point +Movie Theater +Multi-Cache +Museum +Navaid, Amber +Navaid, Black +Navaid, Blue +Navaid, Green +Navaid, Green/Red +Navaid, Green/White +Navaid, Orange +Navaid, Red +Navaid, Red/Green +Navaid, Red/White +Navaid, Violet +Navaid, White +Navaid, White/Green +Navaid, White/Red +Non-directional beacon +Null +Oil Field +Open 24 Hours +Parachute Area +Park +Parking Area +Pharmacy +Picnic Area +Pin, Blue +Pin, Green +Pin, Red +Pizza +Police Station +Post Office +Post Office +Private Field +Radio Beacon +Ramp intersection +Red circle +Red Diamond +Red Letter A +Red Letter B +Red Letter C +Red Letter D +Red Number 0 +Red Number 1 +Red Number 2 +Red Number 3 +Red Number 4 +Red Number 5 +Red Number 6 +Red Number 7 +Red Number 8 +Red Number 9 +Red Oval +Red Rectangle +Red Square +Red Triangle +Reef +Residence +Restaurant +Restricted Area +Restroom +RV Park +Scales +Scenic Area +School +Seafood +Seaplane Base +Shipwreck +Shopping Center +Short Tower +Shower +Ski Resort +Skiing Area +Skull and Crossbones +Small City +Soft Field +Stadium +State Hwy +Steak +Street Intersection +Summit +Swimming Area +TACAN +Tall Tower +Telephone +Tide/Current PRediction Station +Toll Booth +TracBack Point +Trail Head +Truck Stop +Tunnel +U Marina +U stump +Ultralight Area +Unknown Cache +US hwy +VHF Omni-range +Virtual cache +VOR-DME +VOR/TACAN +Water Hydrant +Waypoint +Webcam Cache +Weed Bed +White Buoy +White Dot +Wrecker +Zoo + + diff --git a/xmldoc/chapters/preface.xml b/xmldoc/chapters/preface.xml new file mode 100644 index 000000000..c15306d7f --- /dev/null +++ b/xmldoc/chapters/preface.xml @@ -0,0 +1,25 @@ + + Introduction +
              + The Problem + There are simply too many gratuitously different file formats +to hold waypoint, track, and route information in various programs +used by computers and GPS receivers. +GPX defines a +standard in XML to contain all the data, but there are too many +programs that don't understand it yet and too much data that are in an +alternate formats. + +
              +
              + The Solution + I needed to convert waypoints between a couple of formats, so I +whipped up a converter and based it on an extensible foundation so +that it was easy to add new formats. Most file formats added so far +have taken under 200 lines of reasonable ISO C so they can be stamped +out pretty trivially. Formats that are ASCII text delimited in some +fixed way can be added with no programming at all via our 'style' +mechanism. + +
              +
              diff --git a/xmldoc/chapters/styles.xml b/xmldoc/chapters/styles.xml new file mode 100644 index 000000000..fc8a209f1 --- /dev/null +++ b/xmldoc/chapters/styles.xml @@ -0,0 +1,1104 @@ + +GPSBabel XCSV Style Files + +
              +Introduction + +Often it is desirable to add a new file format for "one-off" work (perhaps +you want to export something to a spreadsheet or graphing program) or to read +a format that GPSBabel does not yet support. For suitably simple formats, +this can be done by a user with no programming experience by providing a +GPSBabel style file. + + +For a format to be described by a style file, it must be predictable and +generally readable by humant. Formats with binary or unreadable content +are not good fits for this scheme. It should have: + +A fixed header at the beginning, if it has any at all. This is called a 'prologue'. +Waypoints that are grouped by fixed separators, often a newline. In style file parlance, this is called a 'record'. +Traits of that waypoint described in that record. In the style files, these are called 'fields' and examples may include longitude or a name. +Fields that are grouped by fixed separators, often a comma or a tab. In the style files, this is called the field separator. +A fixed footer at the end, if it has any at all. This is called the 'epilogue'. + + + +Once you have created a style file that describes the file format you have +or want, you must tell GPSBabel to use the xcsv format and have the xcsv +format use that file. If you created a new style file called +"mystyle.style" and you want to write the waypoints from +a GPX file named "mine.gpx" to it, you would issue a command like: +gpsbabel -i gpx -f mine.gpx -o xcsv,style=mystyle.style -f mine.new +You might then examine mine.new to see if it met +your expectations. If not, you could continue to tweak +mystyle.style until it did, rerunning the above +command each time. If 'mystyle' is a format +that describes a popular program or is likely to be of use to others, you can +then share mystyle.style with other GPSBabel users. +Send it along with a coherent descripton to the GPSBabel-misc mailing +list for consideration to be included in a future version. + +
              +
              +Style file overview + +The first and foremost important step is understanding how the style +file is laid out itself. The format is: + +DIRECTIVE<whitespace>VALUE + +Where <whitespace> is one or more spaces or tabs. There should +be no spaces or tabs at the beginning of the line; all directives start +at the left edge in column zero. + + +An example style format is shown here: + + +# Format: MS S&T 2002/2003 +# Author: Alex Mottram +# Date: 12/09/2002 +# + +DESCRIPTION Microsoft Streets and Trips 2002-2006 +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER TAB +RECORD_DELIMITER NEWLINE +BADCHARS ," + +PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN +# HAVE OUR WAY WITH THE FORMATTING. +# +IFIELD SHORTNAME, "", "%s" # Name +IFIELD LAT_DECIMAL, "", "%f" # Latitude +IFIELD LON_DECIMAL, "", "%f" # Longitude +IFIELD DESCRIPTION, "", "%s" # Name 2 (Big Description) +IFIELD URL, "", "%s" # URL +IFIELD GEOCACHE_TYPE, "", "%s" # Geocache Type +IFIELD GEOCACHE_CONTAINER, "", "%s" # Geocache Type +IFIELD GEOCACHE_DIFF, "", "%3.1f" # Geocache Type +IFIELD GEOCACHE_TERR, "", "%3.1f" # Geocache Type + +Each of these lines will be explained in the following sections. + +
              + +
              +Internal Constants + +A few internal constants are defined in the XCSV parser to make the style +file simpler. They may or may not be used and are optional in most cases. +Note that only certain style file directives map these constants. + + + + +Style Constant +Maps to Char(s) + +COMMA, + + +COMMASPACE,<space> + + +SINGLEQUOTE' + + +DOUBLEQUOTE" + + +COLON: + + +SEMICOLON; + + +NEWLINE\n + + +CR\r + + +CRNEWLINE\r\n + + +TAB\t + + +SPACE<space> + + +HASH# + + +PIPE| + + +WHITESPACEsee below + + + +
              +WHITESPACE + +The WHITESPACE constant has special properties. When reading data, +WHITESPACE refers to sequential runs of SPACES and/or TABS. When +writing data, WHITESPACE is always a single SPACE. + + +For example, the following line: + +SOME_NAME 30.1208 -91.1365 SOME OTHER NAME + + +Parses into the following data fields: + +SOME_NAME,30.1208,-91.1365,SOME,OTHER,NAME + +
              + +
              +COMMENTS + +Anything after a hash (#) on a line is not parsed. For example: + +#THIS ENTIRE LINE IS A COMMENT. +#FIELD LAT_DECIMAL, "", "%f" THIS ENTIRE LINE IS A COMMENT +FIELD LAT_DECIMAL, "", "%f" # ONLY THIS SENTENCE IS A COMMENT. + +
              +
              + +
              +Global Properties of the File + +There are a few available directives to describe general traits of the +file being described and not specific data within the file itself. + +
              +DESCRIPTION + +This is the description of the file format being described. This text +appears in the help screens and in menus used by the various GUI wrappers. + +
              +
              +EXTENSION + +This directive gives the filename extension generally associated with +this file. + +
              +
              +ENCODING + +Describes the character set used by this format. The value given +must be one listed by 'gpsbabel -l'. example: + + ENCODING UTF-8 # Use UTF-8 for input and output. + +
              +
              + +
              +GPSBabel Behavior Directives + +There are a few available directives to control some of the internal +processing functions of GPSbabel. + +
              +SHORTLEN + + This sets the maximum allowed shortname length when using the internal + shortname synthesizer. + + + example: + + SHORTLEN 16 # shortnames will be at most 16 characters long. + +
              + +
              +SHORTWHITE + + This tells the shortname synthesizer whether or not to allow whitespace + in the synthesized shortnames. Allowed values are zero and one. + + + example: + + SHORTWHITE 0 # Do not allow whitespace in shortname. + SHORTWHITE 1 # Allow whitespace in shortname. + +
              +
              + +
              +Defining the Layout of the File + +The first few directives define the layout the physical file itself: + + +
              +FIELD_DELIMITER + + The field delimiter defines the character(s) that separate the fields in + the rows of data inside the XCSV file. Common field delimiters are commas + and tabs. (referred to as "comma separated values" and "tab separated + values") + + + examples: + + FIELD_DELIMITER COMMA + FIELD_DELIMITER ~ + + + The directive FIELD_DELIMITER is parsed for STYLE CONSTANTS as defined in + the table above. + +
              + +
              +RECORD_DELIMITER + + The record delimiter defines that character(s) that separate ROWS of + data (FIELDS) in the XCSV file. The most common record delimiters + are NEWLINE and CR (carriage return). + + + examples: + + RECORD_DELIMITER NEWLINE + RECORD_DELIMITER | + + + The directive RECORD_DELIMITER is parsed for STYLE CONSTANTS as defined + in the table above. + +
              + +
              +BADCHARS + + Bad characters are things that should *never* be written into the XCSV + file as data on output. GPSBabel automatically includes any non-blank + FIELD_DELIMITER and RECORD_DELIMITER characters as BADCHARS by default. + + + examples: + + BADCHARS COMMA + BADCHARS ~| + + + The directive BADCHARS is parsed for STYLE CONSTANTS as defined in the + table above. + +
              + +
              +PROLOGUE + + A prologue is basically constant data that is written to the output + file BEFORE any waypoints are processed. PROLOGUE can be defined + multiple times in the style file, once for each "line" before the data + begins. This is commonly used in XCSV files as a "header" row. + + + examples: + + PROLOGUE OziExplorer Waypoint File Version 1.1 + PROLOGUE WGS 84 + PROLOGUE Symbol,Name,Latitude,Longitude + +
              + +
              +EPILOGUE + + An Epilogue is the same as a prologue, except this data is written at + the END of the file. See the examples for PROLOGUE above. + +
              +
              + +
              +Defining Fields Within the File + +A field defines data. There are two different classifications of FIELDS, +IFIELD (file input) and OFIELD (file output). In the absence of any OFIELDS, +IFIELDS are use as both input and output. The existence of OFIELDS is +primarily to allow more flexible mapping of GPSBabel data to output data +(say, for instance, to map the internal GPSBabel "description" variable to +two or more fields on output). For all practical purposes, IFIELDS and +OFIELDS are defined the same way in the style file. +The following per-field options are defined: + + + + + "no_delim_before" is supported on in OFIELD tags to specify that this + field should be written without a field delimiter before it. It's + useful for limited field concatenation. + + + + + + "absolute" is supported on OFIELD tags for lat and lon to indicate + that only absolute values (never negative) are to be printed. + + + + + + "optional" is supported only OFIELD tags and indicates that the + field may or may not be available in the source data. If the + field is absent, no trailing field separator is written. + + + This attribute is most useful when paired with "no_delim_before" as + it allows you to concatenate fields without concern for whether those + fields are actually populated or not. + + + + + + +There are several different types of fields that may be defined. Each field +consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and +a PRINTF CONVERSION (for output). In many cases, not all pieces are used, +but all 3 pieces are required. Additionally, an fourth field is supported +that modifies the behaviour of the field being described. + + +FIELDS should be defined in the style file in the logical order that they +appear in the data, from left to right. This is the order in which they are +parsed from input and written to output. + + +The fields used by the XCSV parser are as follows: + + +
              +IGNORE + + IGNORE fields are, guess what, ignored on input. Internally, IGNORE + fields are treated as CHARACTER data, and as such, require a printf + conversion for a character array. + + +examples: + + IFIELD IGNORE,"","%14.14s" # (writes a 14 character blank field) + IFIELD IGNORE,"","%s" # (writes a blank field on output) + +
              + +
              +CONSTANT + + CONSTANT fields are, of course, constant. They are ignored on input, + however they write CONSTANT data on output. As such, they require a + DEFAULT VALUE and a printf conversion for a character array. + + +examples: + + IFIELD CONSTANT,"FFFFFF","%s" # (writes "FFFFFF" in the field) + IFIELD CONSTANT,"01/01/70","%s" # (a constant date field) + +
              + +
              +INDEX + + An INDEX field is used ONLY on output. The INDEX constant defines a field + that, at output, contains the sequence number of the waypoint being + written, starting at 0. An index is managed internally as an INTEGER + and requires an INTEGER printf conversion. An INDEX has one special + property. The DEFAULT VALUE of the index is added to the index + on each iteration (to allow indexes starting at 1, 100, etc..). + + +examples: + + IFIELD INDEX,"0","%04d" # (Starts counting at zero) + IFIELD INDEX,"","%04d" # (Starts counting at zero) + IFIELD INDEX,"1","%04d" # (Starts counting at one) + +
              + +
              +SHORTNAME + + A SHORTNAME is generally the waypoint name of the data being processed. + SHORTNAME maps directly to the GPSBabel variable ->shortname. A SHORTNAME + is CHARACTER data and requires a character array printf conversion. + + +example: + + IFIELD SHORTNAME,"","%s" # (write shortname in the output file) + +
              + +
              +DESCRIPTION + + A DESCRIPTION is generally a long description of the waypoint. A + DESCRIPTION maps to the GPSBabel variable ->description and is otherwise + handled exactly like a SHORTNAME. + + +examples: + + IFIELD DESCRIPTION,"","%s" # (write description in the output file) + +
              + +
              +NOTES + + NOTES are generally everything else about a waypoints. NOTES map to the + GPSBabel variable ->notes and is otherwise handled exactly like a + SHORTNAME. + +
              + +
              +URL + + URL is a URL for the waypoint. URL maps to the GPSBabel variable + ->url and is otherwise handled exactly like a SHORTNAME. + + +example: + + IFIELD URL,"","%s" # (writes the URL in the output file) + +
              + +
              +URL_LINK_TEXT + + URL_LINK_TEXT is a textual description of where a URL points. + URL_LINK_TEXT maps to the GPSBabel variable ->url_link_text and + is otherwise handled exactly like a SHORTNAME. + + +example: + + IFIELD URL_LINK_TEXT,"","%s" # (writes link text in the output file) + +
              + +
              +ICON_DESCR + + ICON_DESCR is a textual description of an icon type for a waypoint. + ICON_DESCR maps to the GPSBabel variable ->icon_desc and is otherwise + handled exactly like a SHORTNAME. + + +example: + + IFIELD ICON_DESCR,"","%s" # (writes link text in the output file) + +
              + +
              +LAT_DECIMAL + + LAT_DECIMAL defines LATITUDE in DECIMAL format. Note that this is a PURE + signed decimal format (i.e. -91.0000). This data is handled internally as + a DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf conversion. + + +example: + + IFIELD LAT_DECIMAL,"","%f" + +
              + + +
              +LON_DECIMAL + + See LAT_DECIMAL, except LON_DECIMAL defines LONGITUDE. + +
              + +
              +LAT_INT32DEG + + LAT_INT32DEG defines LATITUDE in what I call INT32DEGREES. This value is + a signed LONG INTEGER and requires a LONG INTEGER printf conversion. + (This format is only used by some DeLorme products.) + + +example: + + IFIELD LAT_INT32DEG,"","%ld" + +
              + +
              +LON_INT32DEG + + See LON_INT32DEG except LON_INT32DEG defines LONGITUDE. + +
              + +
              +LAT_DECIMALDIR / LAT_DIRDECIMAL + + LAT_DECIMALDIR and LAT_DIRDECIMAL define LATITUDE in DECIMAL format + with the added bonus of a 'N/S' or 'E/W' direction character. This data + is handled internally as a DOUBLE PRECISION FLOAT and a single + CHARACTER and requires a FLOATING POINT as well as a CHARACTER printf + conversion. The only difference between the two is whether the directional + character appears before (LAT_DIRDECIMAL) or after (LAT_DECIMALDIR) the + decimal number. + + +examples: + + IFIELD LAT_DECIMALDIR,"","%f %c" # (writes 31.333 N) + IFIELD LAT_DIRDECIMAL,"","%c %f" # (writes N 31.333) + +
              + +
              +LON_DECIMALDIR / LON_DIRDECIMAL + + Same as LAT_DECIMALDIR / LAT_DIRDECIMAL except LON_ defines LONGITUDE. + +
              + +
              +LAT_DIR / LON_DIR + + LAT_DIR returns the single character 'N' or 'S' depending on the + hemisphere of the latitude. LON_DIR returns 'E' or 'W' depending on + the hemisphere of the longitude. + +
              + +
              +LAT_HUMAN_READABLE + + LAT_HUMAN_READABLE defines LATITUDE in a human-readable format. This + format is probably the most expressive format. It is similar to + LAT_DECIMALDIR in that it requires multiple printf conversions, but it + is far more flexible as to the contents of those conversions. On read, + the printf conversions are ignored and GPSBabel attempts to determine the + latitude and longitude based on what is in the file. + + +examples: + + IFIELD LAT_HUMAN_READABLE,"","%c %d %f" # (writes N 31 40.000) + IFIELD LAT_HUMAN_READABLE,"","%d deg %f min %c" + # (writes "31 deg 40.000 min N") + # Note that this string will confuse the reading routine due + # to the letter "n" in "min" and the letter "e" in "deg." + IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" # (writes 31 40 00.000N) + +
              + +
              +LON_HUMAN_READABLE + + See LAT_HUMAN_READABLE except LON_HUMAN_READABLE defines LONGITUDE. + +
              + +
              +LATLON_HUMAN_READABLE + + LATLON_HUMAN_READABLE is like LAT_HUMAN_READABLE and LON_HUMAN_READABLE + except that it reads and writes both latitude and longitude as a single + field. On write, the same format specifier is used for both coordinates. + On read, GPSBabel does exactly the same thing it does for + LAT_HUMAN_READABLE or LON_HUMAN_READABLE. + + +example: + + IFIELD LATLON_HUMAN_READABLE,"","%c %d %f" + # (writes "N 31 40.126 W 85 09.62" as a single field) + +
              + +
              +LAT_NMEA + + Defines the latitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. + + +example: + + IFIELD LAT_NMEA, "%f", "%08.3f" # (writes 3558.322) + +
              + +
              +LON_NMEA + + Defines the longitude in the format used by the NMEA standard which is + degrees multiplied by 100 plus decimal minutes. + + +example: + + IFIELD LON_NMEA, "%f", "%010.3f" # (writes -08708.082) + +
              + +
              +ALT_FEET + + ALT_FEET is the position's ALTITUDE in FEET. This value is treated as + a SIGNED DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf + conversion. + + +example: + + IFIELD ALT_FEET,"","%.0f" + +
              + +
              +ALT_METERS + + ALT_METERS is identical to ALT_FEET with the exception that the altitude + is in METERS. + +
              + +
              +HEART_RATE + + Heart rate, measured in beats per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Forerunner 301). + + +example: + + IFIELD HEART_RATE,"","%d" + +
              + +
              +CADENCE + + Cadence in revolutions per minute. Only valid for units with + heart rate monitor features (i.e. Garmin Edge 305). + + +example: + + IFIELD CADENCE,"","%d" + +
              + +
              +EXCEL_TIME + + EXCEL_TIME is the waypoint's creation time, if any. This is actually + the decimal days since 1/1/1900 and is handled internally as a DOUBLE + PRECISION FLOAT and requires a FLOATING POINT printf conversion. + + +example: + + IFIELD EXCEL_TIME,"","%11.5f" + +
              + +
              +TIMET_TIME + + TIMET_TIME is the waypoint's creation time, if any. This is actually + the integer seconds since 1/1/1970 (let's not start the holy war) and + is handled internally as a LONG INTEGER and requires a LONG INTEGER + printf conversion. + + +example: + + IFIELD TIMET_TIME,"","%ld" + +
              + +
              +YYYYMMDD_TIME + + YYYYMMDD_TIME is the waypoint's creation time, if any. It's a single + decimal field containing four digits of year, two digits of month, + and two digits of date. Internally it is a LONG INTEGER and thus + requires a LONG INTEGER printf conversion. + + +example: + + IFIELD YYYYMMDD_TIME,"","%ld" + +
              + +
              +GMT_TIME + + GMT_TIME is the waypoint's creation time, in UTC time zone. It uses the + strptime conversion format tags. + + +example: + + IFIELD GMT_TIME,"","%m/%d/%Y %I:%M:%D %p" + + + Search the web for 'strptime man page' for details strptime, but one + such page can be found at +http://www.die.net/doc/linux/man/man3/strptime.3.html + +
              + +
              +LOCAL_TIME + + LOCAL_TIME is the waypoint's creation time, in the local + time zone. It uses strptime conversion format tags. See GMT_TIME for a + reference. + + +example: + + IFIELD LOCAL_TIME,"","%y-%m-%d" + +
              + +
              +HMSG_TIME + + HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in UTC. + + +example: + + IFIELD HMSG_TIME,"","%d:%d:%d %s" + +
              + +
              +HMSL_TIME + + HMSG_TIME parses up to three time parts and am/pm string to add + this value to the previously parsed *_TIME field that contains + only a date. On output, will print the time in local time. + + +example: + + IFIELD HMSL_TIME,"","%dh%dm" + +
              + +
              +ISO_TIME + + ISO_TIME is the waypoint's creation time, in ISO 8601 format, + which include time zone information. + It is expected to be in the format yyyy-mm-ddThh:mm:sszzzzz + where zzzzzz is the local time offset or the character Z + for UTC time. + On output, UTC 'Z' time zone will always be used. + + +example: + + IFIELD ISO_TIME,"","%s" + +
              + +
              +GEOCACHE_DIFF + + GEOCACHE_DIFF is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "difficulty" rating as defined by + Groundspeak. A "three and a half star" cache would therefore be "3.5" + + +example: + + IFIELD GEOCACHE_DIFF,"","%3.1f" + +
              + +
              +GEOCACHE_TERR + + GEOCACHE_TERR is valid only for geocaches and represents a DOUBLE + PRECISION FLOAT. This is the geocache "terrain" rating as defined + by Groundspeak. A "three and a half star" cache would therefore be "3.5" + + +example: + + IFIELD GEOCACHE_TERR,"","%3.1f" + +
              + +
              +GEOCACHE_CONTAINER + + GEOCACHE_CONTAINER is valid only for geocaches and is heavily influenced + by the Groundspeak container types. Examples would include "Micro" + and "Virtual". + + +example: + + GEOCACHE_CONTAINER,"","%s" + +
              + +
              +GEOCACHE_TYPE + + GEOCACHE_TYPE is valid only for geocaches and is heavily influenced + by the Groundspeak cache types. Examples would include "Event cache" + and "Multi-Cache". + + +example: + + GEOCACHE_TYPE,"","%s" + +
              + +
              +GEOCACHE_PLACER + + GEOCACHE_PLACER is a string containing the name of the placer of a + geocache. + + +example: + + GEOCACHE_PLACER,"","%s" + +
              + +
              +GEOCACHE_LAST_FOUND + + A long integer in format YYYYMMDD containing the last time this geocache + was found. + + +example: + + GEOCACHE_LAST_FOUND,"","%ld" + +
              + +
              +GEOCACHE_HINT + + The hint for this geocache. No additional transformation (such as rot13) + will be performed on this string. + + +example: + + GEOCACHE_HINT,"","%s" + +
              + +
              +PATH_DISTANCE_MILES + + PATH_DISTANCE_MILES outputs the total length of the route or track from + the start point to the current point, in miles. This and the altitude + could be used to create an elevation profile. PATH_DISTANCE_MILES is + a DOUBLE PRECISION FLOAT. + + + PATH_DISTANCE_MILES is not valid as an input field. + + + PATH_DISTANCE_MILES is only meaningful if the data comes from a track + or a route; waypoint data will generate essentially meaningless output. + + +example: + + PATH_DISTANCE_MILES,"","%f" + +
              + +
              +PATH_DISTANCE_KM + + PATH_DISTANCE_KM is like PATH_DISTANCE_MILES except it outputs the + length in kilometers. + +
              + +
              +PATH_SPEED + + Speed in meters per second. Gpsbabel does NOT calculate this data by + default; it is read from the input file if present. (If not present, + it may be calculated with the track + filter.) + + +example: + + PATH_SPEED,"","%f" + +
              + +
              +PATH_COURSE + + Course in degerees. Gpsbabel does not calculate this data by default; + it is read from the input file if present. (If not present, it may be + calculated with the track filter.) + + +example: + + PATH_COURSE,"","%f" + +
              + +
              +GPS_HDOP / GPS_VDOP / GPS_PDOP + + GPS horizontal / vertical / positional dilution of precision + parameters. Needs float conversion. + + +example: + + GPS_HDOP,"","%f" + +
              + +
              +GPS_SAT + + Number of satellites used for determination of the position. Needs + integer conversion. + + +example: + + GPS_SAT,"","%d" + +
              + +
              +GPS_FIX + + Type of fix (see GPX spec or track +filter). Needs string conversion. + + +example: + + GPS_FIX,"","%s" + +
              +
              + +
              +Examples + +Here is one example style file from the GPSBabel source. + +# gpsbabel XCSV style file +# +# Format: Garmin POI +# Author: Robert Lipe +# Date: 10/07/2005 +# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204 +# +DESCRIPTION Garmin POI database +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +SHORTLEN 24 + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LON_HUMAN_READABLE, "", "%08.5f" +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" + +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD SHORTNAME, "", "%-.24s" +OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional" +OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional" +OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional" +OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional" +OFIELD DESCRIPTION, "", "%-.50s" + +When used on a Groundspeak Pocket Query, it will output lines that +look like: + +-76.76234,38.39123,GC5370 Loca/Virt (1.0/1.0),Dude.. Wheres my Limo?? +-90.42345,38.55234,GCC8B Trad/Regu (2.0/2.0),Sweet Reward +-90.81456,38.62456,GC3091 Trad/Regu (1.5/2.0),Matson Hill + +that are suitable for Garmin's POI loader. + + +For additional examples, please see the +*.style files in the +style/ subdirectory of GPSBabel or at the online source tree. + +
              + +
              +Miscellaneous Notes +
              +Default Values + +Default values are supported for any output fields that contain pure + character data output such as URL and NOTES. Default values are only + written on output and are not used to supplement missing input. When + using default values your mileage will vary greatly depending on the + input formats used to populate waypoint data. + +
              +
              + +
              diff --git a/xmldoc/chapters/use.xml b/xmldoc/chapters/use.xml new file mode 100644 index 000000000..df0109323 --- /dev/null +++ b/xmldoc/chapters/use.xml @@ -0,0 +1,265 @@ + + Usage + + Invocation + Invocation was meant to be flexible. Unfortunately, + that can sometimes lead to unwieldy command lines. + + +If you're using GPSBabel, you will need to know how to do at least two things: +read data from a file, and write it to another file. There are four basic +commands you need to know to do those things: + + + +Command +Meaning + + format + Set input format + + + filename + Read file + + + format + Set output format + + + filename + Write output File + + + + +The format parameters in the above list +refer to the names of formats or file types supported by GPSBabel. + +gpsbabel -? +will always show you the supported file types. In this document, the +various supported formats are listed in . The +name that you would use on the command line follows the format name in +parentheses. + + +The filename parameters specify the +name of a file to be read or written. + + +To use + this program, just tell it what you're reading, where to read + it from, what you're writing, and what to write it to. For + example: + gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx + tells it to read the file "/tmp/geocaching.loc" in geocaching.com + format and create a new file in GPX format. + This command will read from a Magellan unit attached + to the first serial port on a Linux system (device names will + vary on other OSes) and write them as a geocaching loc file. + The second command does the same on Microsoft Windows. + gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc + gpsbabel -i magellan -f com1 -o geo -F mag.loc + Optionally, you may specify "-s" in any command line. This + causes the program to ignore any "short" names that may be + present in the source data format and synthesize one from the + long name. This is particularly useful if you're writing to + a target format that isn't the lowest common denominator but + the source data was written for the lowest common + denominator. I use this for writing data from geocaching.com + to my Magellan so my waypoints have "real" names instead of + the 'GC1234' ones that are optimized for NMEA-only receivers. + A geocacher with a Magellan receiver may thus find commands + like this useful. + gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 + gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1 + + + Advanced Usage + Argument are processed in the order they appear on the command +line and are translated internally into a pipeline that data flows +through when executed. Normally one would: + + read from one input + optionally apply filters + write into one output + + but GPSBabel is flexible enough to allow more complicated +operations such as reading from several files (potentially of +different types), applying a filter, reading more data, then write the +merged data to multiple destinations. + + The input file type remains unchanged until a new + -i argument is seen. + Files are read in the order they appear. So you could merge + three input files into one output file with: + gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc + You can merge files of different types: + gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx \ +-o gpsutil -F big.gps + You can write the same data in different output formats: + gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt + If you want to change the character set of input or/and + output side you can do this with the option . You can get a complete list + of supported character sets with "gpsbabel -l". To change + the character set on both sides you should do this: + gpsbabel -i xcsv,style=foo.style -c latin1 -f foo \ + -o xcsv,style=bar.style -c ms-ansi -F bar + Note, that some formats has a fixed character set and ignore this option. + + + Route and Track Modes + Most formats will make reasonable attempt to work + transparently with waypoints, tracks, and routes. Some + formats, like 'garmin' and 'magellan' require the -t flag to work with tracks and + -r to work with + routes. -w is for + waypoints, and is the default. So if you wanted to read all + data from your unit into a gpx file, you might use a command + like: + gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx + Tracks and routes are advanced features and don't try + to handle every possible hazard that can be encountered + during a conversion. If you're merging or converting files + of similar limitations, things work very well. + Tracks and routes will sometimes be converted to a + list of waypoints when necessary, f.i. when writing into one + of the CSV formats. The inverse operation is not supported + right now, so reading the converted track back from CSV will + always result in a list of waypoints, not the original track. + + The presence of -s on the command line tends to + creats havoc on tracks and routes since many of these formats + rely on internal linkages between such points and renaming + them may break those linkages. In general, don't use + -s when tracks or + routes are present. + + + + Working with predefined options + + GPSBabel can read a file on startup to set defaults for options. All + module and filter options may be set this way. + + + + The format of the file is identical to the inifile-format often seen + on Windows. Here is an example: + + + + [Common format settings] + snupper=Y + snlen=10 + [gpx] + gpxver=1.1 + [magellan] + baud=115200 + [tiger] + [Garmin categories] + ; any # from 1 to 16 + 1=fixed waypoints + 2=temporary waypoints + + + Each section of the file starts with a '[section]' header followed by any + number of lines formatted option=value. Leading and trailing whitespace + will be + automatically removed from header, option and value items. + + Lines starting + with '#' or ';' will be treated as comments and ignored. + + + + There are three optional sections. + + + "Common format settings" + Any option from any of the formats listed here will be used by + GPSBabel unless explictly provided on the command line. + + + + "Common filter settings" + As above, but for filters. + + + Garmin categories + This allows you to give readable names to the numeric categories + used internally in some Garmin devices and the Mapsource formats + such as GDB and MPS. This is information is also used by our GPX + and garmin_txt formats as well. + + + + + + By default, GPSBabel tries at startup to load the file named + gpsbabel.ini from the following locations: + + + current working directory + Windows: all paths "APPDATA", "WINDIR", "SYSTEMROOT" declared in environment. + Unix like OS'ses: ${HOME}/.gpsbabel/, /usr/local/etc/ and /etc/ + + + If the option is specified, the above locations are not searched. + Only the filename specified by that option will be used. + + + There may be situations where predefined values are not useable + (i.e. wrapper applications using GPSBabel in the background). + The inifile mechanism can be disabled with an empty filename. + + gpsbabel -p "" -i gpx -f something.gpx -o tiger -F - + + + Realtime tracking + + Introduced in GPSBabel 1.3.1, we now have an experimental feature for realtime tracking via the new '-T' option. This reads position reports from selected formats and writes an output file when a position report is received. + + + As of this writing, Garmin's PVT protocol and NMEA are supported + inputs and KML is supported on output. Additional formats + may be added by interested parties later. + + + gpsbabel -T -i garmin -f usb: -o kml -F xxx.kml + Will read the USB-connected Garmin and rewrite 'xxx.kml' atomically, + suitable for a self-refreshing network link in Google Earth. + + + + + Batch mode (command files) + + In addition to reading arguments from the command line, GPSBabel can + read directions from batch (or command) files via the '-b' option. + + + These files are ideal for holding long command lines, long file lists, complex filters + and so on. You can use all GPSBabel options and combinations when writing + such files. Nesting batch files by using the '-b' option within a batch file is supported. + + + Here is an example demonstrating segmenting a large command line + by placing the input and filtering directives in a file called 'all_my_files'. + gpsbabel -b all_my_files -o gdb -F all_my_tracks.gdb + + + 'all_my_files' could look like this: + + + -i gpx + -f saxony_in_summer_2004.gpx -f austria_2005.gpx + -i gdb + -f croatia_2006.gdb + -x nuketypes,waypoints,routes + -x track,pack,split,title="LOG # %Y%m%d" + + + diff --git a/xmldoc/filters/arc.xml b/xmldoc/filters/arc.xml new file mode 100644 index 000000000..e3a032dc6 --- /dev/null +++ b/xmldoc/filters/arc.xml @@ -0,0 +1,42 @@ + +This filter keeps or removes waypoints based on their proximity to an arc, +which is a series of connected line segments similar to a route or a track +but without any associated data other than the coordinates. + + + +The arc is defined in a file whose name must be provided with the +. That file contains pairs of coordinates for the +vertices of the arc, one coordinate pair per line. Comments may be +included by preceding them with a '#' character. An arc file looks +something like this sample: + + + +# Lima Road/SR3 north of Fort Wayne, Indiana +41.150064468 -85.166207433 +41.150064468 -85.165371895 +41.149034500 -85.165157318 +41.147832870 -85.164771080 +41.146631241 -85.164384842 +41.144270897 -85.163655281 +41.141953468 -85.162882805 + + + +An arc file may optionally contain gaps in the arc. You may specify +such a gap by inserting a line containing "#break" either on a line by +itself or after the coordinates of the starting point of the new arc segment. + + + +Using the arc filter + +Assuming the arc above is in a file called +lima_rd.txt, the following command line +would include only points within one mile of the section of Lima Road +covered by the arc. + +gpsbabel -i geo -f 1.loc -x arc,file=lima_rd.txt,distance=1 -o mapsend -F 2.wpt + + diff --git a/xmldoc/filters/discard.xml b/xmldoc/filters/discard.xml new file mode 100644 index 000000000..962549f65 --- /dev/null +++ b/xmldoc/filters/discard.xml @@ -0,0 +1,12 @@ + +This filter is used to "fix" unreliable GPS data by discarding points +with HDOP and/or VDOP above a specified limit. HDOP and VDOP are +measures of the best possible horizontal or vertical precision +for a given configuration of GPS satellites. + + +Using the discard filter + gpsbabel -i gpx -f in.gpx -x discard,hdop=10,vdop=20,hdopandvdop -o gpx -F out.gpx + + Contributed by Tobias Minich. + diff --git a/xmldoc/filters/duplicate.xml b/xmldoc/filters/duplicate.xml new file mode 100644 index 000000000..79b85af9d --- /dev/null +++ b/xmldoc/filters/duplicate.xml @@ -0,0 +1,20 @@ + +The duplicate filter is designed to remove duplicate points based on their +short name (traditionally a waypoint's name on the GPS receiver), and/or +their location (to a precision of 6 decimals). This filter supports two +options that specify how duplicates will be recognized, + and . +Generally, at least one of these options is required. + + + Using the duplicate filter to suppress points with the same + name and location + + This command line removes points that have duplicate short names + and duplicate locations. The result would be a + gpx file that more than likely + contains only unique points and point data. + + gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname -o gpx -F merged_with_no_dupes.gpx + + diff --git a/xmldoc/filters/interpolate.xml b/xmldoc/filters/interpolate.xml new file mode 100644 index 000000000..2b08aec0a --- /dev/null +++ b/xmldoc/filters/interpolate.xml @@ -0,0 +1,30 @@ + +This filter modifies any tracks so that either the distance or the time +between consecutive points is no less than the specified interval. Where +points are missing, the filter fills them in by following a straight +line (actually a great circle) between the adjacent points. You +must specify either the + or the option. + + +Using the interpolate filter + +This command line reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 10 seconds apart: + +gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -F newtrack.gpx + + +This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 15 kilometers apart: + + +gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -F newtrack.gpx + + +This command reads track.gpx and inserts points wherever two adjacent +trackpoints are more than 2 miles apart: + + +gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -F newtrack.gpx + diff --git a/xmldoc/filters/nuketypes.xml b/xmldoc/filters/nuketypes.xml new file mode 100644 index 000000000..824f20d56 --- /dev/null +++ b/xmldoc/filters/nuketypes.xml @@ -0,0 +1,16 @@ + +There are three main types of data that GPSBabel deals with: +waypoints, tracks, and routes. The nuketypes filter allows +removing all the data of any or all of those three types. + + +Filtering data types with nuketypes + +If you have a GPX file that contains routes, tracks, and +waypoints and you want a GPX file that contains only tracks, +you may use this filter to remove the waypoints and the routes +with this command: + +gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx + + diff --git a/xmldoc/filters/options/arc-distance.xml b/xmldoc/filters/options/arc-distance.xml new file mode 100644 index 000000000..83a3189ec --- /dev/null +++ b/xmldoc/filters/options/arc-distance.xml @@ -0,0 +1,14 @@ + +This option is not required, but if it is not specified the distance +defaults to zero miles, which isn't very useful. + + +This option specifies the maximum distance a point may be from the arc +without being discarded. Points that are closer to the arc are kept, while +points that are further away are discarded. + + +Distances may be specified in miles (3M) or kilometers (5K). If no units +are specified, the distance is assumed to be in miles. + + diff --git a/xmldoc/filters/options/arc-exclude.xml b/xmldoc/filters/options/arc-exclude.xml new file mode 100644 index 000000000..37f84b3ba --- /dev/null +++ b/xmldoc/filters/options/arc-exclude.xml @@ -0,0 +1,6 @@ + +When this option is specified, the usual sense of the arc filter is reversed. +That is, points that are closer than distance are discarded +while points that are further away are kept. + + diff --git a/xmldoc/filters/options/arc-file.xml b/xmldoc/filters/options/arc-file.xml new file mode 100644 index 000000000..6316b64c4 --- /dev/null +++ b/xmldoc/filters/options/arc-file.xml @@ -0,0 +1,13 @@ + +This option is required. + + +This option specifies the name of the file containing the arc to use for +filtering. The format of the file is as described above. + + +GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. + + diff --git a/xmldoc/filters/options/arc-points.xml b/xmldoc/filters/options/arc-points.xml new file mode 100644 index 000000000..5f1c7d347 --- /dev/null +++ b/xmldoc/filters/options/arc-points.xml @@ -0,0 +1,11 @@ + +When this option is specified, only points that are within the specified +distance of one of the vertices of the arc are kept. This differs from the +normal mode of operation in that in the normal mode, points that are close to +the lines between points are also kept. + + +This option makes the arc filter act like a multi-point version of the +radius filter. + + diff --git a/xmldoc/filters/options/discard-hdop.xml b/xmldoc/filters/options/discard-hdop.xml new file mode 100644 index 000000000..8fcc16080 --- /dev/null +++ b/xmldoc/filters/options/discard-hdop.xml @@ -0,0 +1,7 @@ + +This option specifies the maximum allowable Horizontal Dilution of +Precision (HDOP). By default, any point with an HDOP in excess of +this value will be discarded regardless of its VDOP, but see +. + + diff --git a/xmldoc/filters/options/discard-hdopandvdop.xml b/xmldoc/filters/options/discard-hdopandvdop.xml new file mode 100644 index 000000000..d07dd4144 --- /dev/null +++ b/xmldoc/filters/options/discard-hdopandvdop.xml @@ -0,0 +1,6 @@ + +If this option is used, only points that exceed both the maximum +allowable HDOP and the maximum allowable VDOP will be discarded. This +option requires that both the and + options be specified. + diff --git a/xmldoc/filters/options/discard-vdop.xml b/xmldoc/filters/options/discard-vdop.xml new file mode 100644 index 000000000..f8701abd8 --- /dev/null +++ b/xmldoc/filters/options/discard-vdop.xml @@ -0,0 +1,7 @@ + +This option specifies the maximum allowable Vertical Dilution of +Precision (VDOP). By default, any point with an VDOP in excess of +this value will be discarded regardless of its HDOP, but see +. + + diff --git a/xmldoc/filters/options/duplicate-all.xml b/xmldoc/filters/options/duplicate-all.xml new file mode 100644 index 000000000..582a64b28 --- /dev/null +++ b/xmldoc/filters/options/duplicate-all.xml @@ -0,0 +1,17 @@ + +When this option is specified, GPSBabel will remove all instances of a +duplicated waypoint, not just the second and subsequent instances. If +your input file contains waypoints A, B, B, and C, the output file will +contain waypoints A, B, and C without the option, +or just A and C with the option. + + +Using the duplicate filter to implement an "ignore list." + +This option may be used to implement an "ignore list." In the following +example, the duplicate filter is used to remove a list of waypoints to be +ignored from a larger collection of waypoints: + +gpsbabel -i gpx -f waypoints.gpx -i csv -f to_ignore.csv -x duplicate,shortname,all -o gpx -F filtered.gpx + + diff --git a/xmldoc/filters/options/duplicate-correct.xml b/xmldoc/filters/options/duplicate-correct.xml new file mode 100644 index 000000000..20741d15b --- /dev/null +++ b/xmldoc/filters/options/duplicate-correct.xml @@ -0,0 +1,21 @@ + +This option is used to change the locations of waypoints without losing any +of the other associated information. When this option is specified, the +latitude and longitude from later duplicates will replace the latitude and +longitude in the original waypoint. + + +As an example, this option may be used to adjust the locations of "puzzle" +geocaches in a Groundspeak pocket query: + + +Using the duplicate filter to correct the locations of "puzzle" +geocaches +gpsbabel -i gpx -f 43622.gpx -i csv -f corrections.csv -x duplicate,shortname,correct -o gpx -F 43622-corrected.gpx + +After this command is run, the waypoints in the output file will have all +of the descriptive information from 43622.gpx, but +waypoints that were also found in corrections.csv +will have their coordinates replaced with the coordinates from that file. + + diff --git a/xmldoc/filters/options/duplicate-location.xml b/xmldoc/filters/options/duplicate-location.xml new file mode 100644 index 000000000..910bfc30c --- /dev/null +++ b/xmldoc/filters/options/duplicate-location.xml @@ -0,0 +1,9 @@ + +This option causes the duplicate filter to remove any additional waypoint +that has the same coordinates (to six decimal degrees) as a waypoint that +came before. This option may be used to remove duplicate waypoints if the +names are not expected to be the same. It also might be used along with the + option to remove duplicate waypoints if the names +of several unrelated groups of waypoints might be the same. + + diff --git a/xmldoc/filters/options/duplicate-shortname.xml b/xmldoc/filters/options/duplicate-shortname.xml new file mode 100644 index 000000000..72f88c2fc --- /dev/null +++ b/xmldoc/filters/options/duplicate-shortname.xml @@ -0,0 +1,9 @@ + +This option is the one most often used with the duplicate filter. This +option instructs the duplicate filter to remove any waypoints that share +a short name with a waypoint that has come before. This option might be +used to remove duplicates if you are merging two datasets that were +each created in part from a common ancestor dataset. + + + diff --git a/xmldoc/filters/options/interpolate-distance.xml b/xmldoc/filters/options/interpolate-distance.xml new file mode 100644 index 000000000..4cef24f6b --- /dev/null +++ b/xmldoc/filters/options/interpolate-distance.xml @@ -0,0 +1,13 @@ + +This option specifies the maximum allowable distance between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. + + +This value may be specified in units of miles (3M) or kilometers (5K). If +no units are specified, the units are assumed to be miles. + + +Either this option or the must be specified. + + diff --git a/xmldoc/filters/options/interpolate-route.xml b/xmldoc/filters/options/interpolate-route.xml new file mode 100644 index 000000000..1605b9f6c --- /dev/null +++ b/xmldoc/filters/options/interpolate-route.xml @@ -0,0 +1,5 @@ + +If this option is specified, the interpolate filter interpolates routes +rather than tracks. Because route points do not have time stamps, it is an +error to use this option with the option. + diff --git a/xmldoc/filters/options/interpolate-time.xml b/xmldoc/filters/options/interpolate-time.xml new file mode 100644 index 000000000..4bdfe5669 --- /dev/null +++ b/xmldoc/filters/options/interpolate-time.xml @@ -0,0 +1,12 @@ + +This option specifies the maximum allowable time interval between points in the +track. If two points in the track are further apart than this value, new +points will be inserted between them. + + +This value is always specified in units of seconds. + + +Either this option or the must be specified. + + diff --git a/xmldoc/filters/options/nuketypes-routes.xml b/xmldoc/filters/options/nuketypes-routes.xml new file mode 100644 index 000000000..9c70b59ba --- /dev/null +++ b/xmldoc/filters/options/nuketypes-routes.xml @@ -0,0 +1,4 @@ + +This option causes the nuketypes filter to discard all route data. + + diff --git a/xmldoc/filters/options/nuketypes-tracks.xml b/xmldoc/filters/options/nuketypes-tracks.xml new file mode 100644 index 000000000..536c9d6cc --- /dev/null +++ b/xmldoc/filters/options/nuketypes-tracks.xml @@ -0,0 +1,4 @@ + +This option causes the nuketypes filter to discard all track data. + + diff --git a/xmldoc/filters/options/nuketypes-waypoints.xml b/xmldoc/filters/options/nuketypes-waypoints.xml new file mode 100644 index 000000000..26c71901e --- /dev/null +++ b/xmldoc/filters/options/nuketypes-waypoints.xml @@ -0,0 +1,5 @@ + +This option causes the nuketypes filter to discard all waypoints that are not +associated with a track or route. + + diff --git a/xmldoc/filters/options/polygon-exclude.xml b/xmldoc/filters/options/polygon-exclude.xml new file mode 100644 index 000000000..6a68bdfa2 --- /dev/null +++ b/xmldoc/filters/options/polygon-exclude.xml @@ -0,0 +1,6 @@ + +When this option is specified, the usual sense of the polygon filter is +reversed. That is, points that are inside the polygon are discarded +while points that are further away are kept. + + diff --git a/xmldoc/filters/options/polygon-file.xml b/xmldoc/filters/options/polygon-file.xml new file mode 100644 index 000000000..032b595c1 --- /dev/null +++ b/xmldoc/filters/options/polygon-file.xml @@ -0,0 +1,16 @@ + +This option is required. + + +This option specifies the name of the file containing the polygon to use for +filtering. The format of the file is as described above. + + +GPSBabel supports converting any route or track to a file usable by this +filter; simply read it in the normal way and write it using the +arc file format. Afterward, you will +need to make sure that the first point and the last point in the +file are the same, as the polygon filter depends on that. You can do so +with any text editor. + + diff --git a/xmldoc/filters/options/position-all.xml b/xmldoc/filters/options/position-all.xml new file mode 100644 index 000000000..16e59e5a8 --- /dev/null +++ b/xmldoc/filters/options/position-all.xml @@ -0,0 +1,8 @@ + +This option causes the position filter to remove all points that are within +the specified distance of one another, rather than leaving just one of them. + + +This option may be used to entirely remove clusters of points. + + diff --git a/xmldoc/filters/options/position-distance.xml b/xmldoc/filters/options/position-distance.xml new file mode 100644 index 000000000..ebd18d5d9 --- /dev/null +++ b/xmldoc/filters/options/position-distance.xml @@ -0,0 +1,9 @@ + +This option specifies the minimum allowable distance between two points. If +two points are closer than this distance, only one of them is kept. + + +Distances may be expressed in feet (30f) or meters (10m). If no unit is +specified, the distance is assumed to be in feet. + + diff --git a/xmldoc/filters/options/radius-asroute.xml b/xmldoc/filters/options/radius-asroute.xml new file mode 100644 index 000000000..4cd6539f9 --- /dev/null +++ b/xmldoc/filters/options/radius-asroute.xml @@ -0,0 +1,13 @@ + +This option specifies the name of a route. If this option is specified, the +radius filter puts all points that are kept into a route with the given name. +The order of points in the route is by distance from the center (unless the + option is also specified.) + + +Note that this route is not necessarily the most efficient route to visit +all of the points. In fact, for some data sets, it might be the least +efficient route. + + + diff --git a/xmldoc/filters/options/radius-distance.xml b/xmldoc/filters/options/radius-distance.xml new file mode 100644 index 000000000..7e4ff8212 --- /dev/null +++ b/xmldoc/filters/options/radius-distance.xml @@ -0,0 +1,13 @@ + +This option is required. + + +This option specifies the maximum distance a point may be from the central +point in order to remain in the dataset. Points closer than this distance +will be kept and points further away will be removed (unless the + option is specified.) + + +Distances may be expressed in miles (3M) or kilometers (4K). If no units +are provided, the distance is assumed to be in miles. + diff --git a/xmldoc/filters/options/radius-exclude.xml b/xmldoc/filters/options/radius-exclude.xml new file mode 100644 index 000000000..434a35b80 --- /dev/null +++ b/xmldoc/filters/options/radius-exclude.xml @@ -0,0 +1,5 @@ + +If this option is included, the action of the radius filter will be reversed: +points within the given distance will be removed, and points further away +will be kept. + diff --git a/xmldoc/filters/options/radius-lat.xml b/xmldoc/filters/options/radius-lat.xml new file mode 100644 index 000000000..bfe5c23e9 --- /dev/null +++ b/xmldoc/filters/options/radius-lat.xml @@ -0,0 +1,8 @@ + +This option is required. + + +This option specifies the latitude of the central point in decimal degrees. +South latitudes should be expressed as a negative number. Valid values for +this option are from -90 to 90. + diff --git a/xmldoc/filters/options/radius-lon.xml b/xmldoc/filters/options/radius-lon.xml new file mode 100644 index 000000000..cca861e5a --- /dev/null +++ b/xmldoc/filters/options/radius-lon.xml @@ -0,0 +1,8 @@ + +This option is required. + + +This option specifies the longitude of the central point in decimal degrees. +West longitudes should be expressed as a negative number. Valid values for +this option are from -180 to 180. + diff --git a/xmldoc/filters/options/radius-maxcount.xml b/xmldoc/filters/options/radius-maxcount.xml new file mode 100644 index 000000000..2ca05844d --- /dev/null +++ b/xmldoc/filters/options/radius-maxcount.xml @@ -0,0 +1,22 @@ + +This option specifies the maximum number of points that the radius filter may +keep. If there are more than this number of points within the specified +distance of the center, the more distant points will be discarded even though +they are within the specified distance. If this option is not specified, +all points are kept regardless of how many there are. + + +Note that if the option is also specified, this +option will instead keep points based on their position within the input +file rather than on their distance from the center. This may or may not be +what you want. + + +Note, too, that this option may be used with the +option, but the results might not be what you expect. In particular, the +results will not be the same as if you had kept all of the points you'd +otherwise throw away. You will still get no more than +maxcount points, but they will all be at least +distance away from the center. (And possibly sorted.) + + diff --git a/xmldoc/filters/options/radius-nosort.xml b/xmldoc/filters/options/radius-nosort.xml new file mode 100644 index 000000000..42ba6d5e5 --- /dev/null +++ b/xmldoc/filters/options/radius-nosort.xml @@ -0,0 +1,6 @@ + +If this option is specified, the radius filter will not sort the remaining +points by distance from the center. They will remain in whatever order they +were originally. + + diff --git a/xmldoc/filters/options/simplify-count.xml b/xmldoc/filters/options/simplify-count.xml new file mode 100644 index 000000000..9b268a3c9 --- /dev/null +++ b/xmldoc/filters/options/simplify-count.xml @@ -0,0 +1,8 @@ + +This option specifies the maximum number of points which may appear in the +simplified route. For example, if you specify "count=50", all resulting +routes will contain 50 points or fewer. + + +You must specify either this option or the option. + diff --git a/xmldoc/filters/options/simplify-crosstrack.xml b/xmldoc/filters/options/simplify-crosstrack.xml new file mode 100644 index 000000000..3b3c2831e --- /dev/null +++ b/xmldoc/filters/options/simplify-crosstrack.xml @@ -0,0 +1,11 @@ + +This option instructs GPSBabel to remove points that have the smallest +overall effect on the overall shape of the route. Using this method, the +first point to be removed will be the one that is closest to a line drawn +between the two points adjacent to it. + + +If neither this option nor the option is specified, +this is the default. + + diff --git a/xmldoc/filters/options/simplify-error.xml b/xmldoc/filters/options/simplify-error.xml new file mode 100644 index 000000000..dec87de10 --- /dev/null +++ b/xmldoc/filters/options/simplify-error.xml @@ -0,0 +1,13 @@ + +This option specifies the maximum allowable error that may be introduced +by removing a single point. The value of this option is a distance, +specified in miles by default. You may also specify the distance in +kilometers by adding a 'k' to the end of the number. + + +How the error is determined depends on whether the +or method is used. If you are using the length +method, the error is the change in the length of the route introduced by +removing a point. If you are using the crosstrack method, the error is the +distance from the point to the line that results if that point is removed. + diff --git a/xmldoc/filters/options/simplify-length.xml b/xmldoc/filters/options/simplify-length.xml new file mode 100644 index 000000000..0842f2f1f --- /dev/null +++ b/xmldoc/filters/options/simplify-length.xml @@ -0,0 +1,4 @@ + +This option instructs GPSBabel to simplify by removing points that cause the +smallest change in the overall length of the route first. + diff --git a/xmldoc/filters/options/sort-description.xml b/xmldoc/filters/options/sort-description.xml new file mode 100644 index 000000000..c629fce01 --- /dev/null +++ b/xmldoc/filters/options/sort-description.xml @@ -0,0 +1,8 @@ + +This option causes the waypoints to be sorted in alphabetical order by +description. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/sort-gcid.xml b/xmldoc/filters/options/sort-gcid.xml new file mode 100644 index 000000000..c2431b778 --- /dev/null +++ b/xmldoc/filters/options/sort-gcid.xml @@ -0,0 +1,8 @@ + +If the data contains Groundspeak geocache IDs, this option causes the +waypoints to be sorted in alphabetical order by geocache ID. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/sort-shortname.xml b/xmldoc/filters/options/sort-shortname.xml new file mode 100644 index 000000000..cd4075ccb --- /dev/null +++ b/xmldoc/filters/options/sort-shortname.xml @@ -0,0 +1,8 @@ + +This option causes the waypoints to be sorted in alphabetical order by +short name. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/sort-time.xml b/xmldoc/filters/options/sort-time.xml new file mode 100644 index 000000000..c43f60902 --- /dev/null +++ b/xmldoc/filters/options/sort-time.xml @@ -0,0 +1,8 @@ + +This option causes the waypoints to be sorted in chronological order by +creation time. + + +This option is not valid in combination with any other option. + + diff --git a/xmldoc/filters/options/stack-append.xml b/xmldoc/filters/options/stack-append.xml new file mode 100644 index 000000000..eb4299e05 --- /dev/null +++ b/xmldoc/filters/options/stack-append.xml @@ -0,0 +1,5 @@ + +This option is only valid in conjunction with the . +When it is specified, the topmost collection of data from the stack is +appended to the current collection of data. + diff --git a/xmldoc/filters/options/stack-copy.xml b/xmldoc/filters/options/stack-copy.xml new file mode 100644 index 000000000..ae9fe8449 --- /dev/null +++ b/xmldoc/filters/options/stack-copy.xml @@ -0,0 +1,6 @@ + +This option is only valid when used with the option. +When this option is specified, a copy of the current state is pushed onto +the stack but the current state is left unchanged. Otherwise, the push +operation clears the current data collection. + diff --git a/xmldoc/filters/options/stack-depth.xml b/xmldoc/filters/options/stack-depth.xml new file mode 100644 index 000000000..2103d5d59 --- /dev/null +++ b/xmldoc/filters/options/stack-depth.xml @@ -0,0 +1,6 @@ + +This option is only valid when used along with the +option. If specified, it indicates which item on the stack should be +swapped with the current state. The default value is 1, which corresponds +to the top of the stack. + diff --git a/xmldoc/filters/options/stack-discard.xml b/xmldoc/filters/options/stack-discard.xml new file mode 100644 index 000000000..a4765b69d --- /dev/null +++ b/xmldoc/filters/options/stack-discard.xml @@ -0,0 +1,5 @@ + +This option is only valid when used with the option. +When this option is specified, the popped state is discarded and the current +state remains unchanged. + diff --git a/xmldoc/filters/options/stack-pop.xml b/xmldoc/filters/options/stack-pop.xml new file mode 100644 index 000000000..0bfb71660 --- /dev/null +++ b/xmldoc/filters/options/stack-pop.xml @@ -0,0 +1,9 @@ + +This is one of three "primary" options to the stack filter. + + +This option "pops" the collection of data from the top of the stack. +By default, the saved state replaces the current state, but see the + and options for +alternatives. + diff --git a/xmldoc/filters/options/stack-push.xml b/xmldoc/filters/options/stack-push.xml new file mode 100644 index 000000000..8f76ad567 --- /dev/null +++ b/xmldoc/filters/options/stack-push.xml @@ -0,0 +1,8 @@ + +This is one of three "primary" options to the stack filter. + + +When this option is specified, the current state is pushed onto the top of +the stack. By default, the current state is then cleared, but the + option can be used to cause it to be saved. + diff --git a/xmldoc/filters/options/stack-replace.xml b/xmldoc/filters/options/stack-replace.xml new file mode 100644 index 000000000..2e967fdba --- /dev/null +++ b/xmldoc/filters/options/stack-replace.xml @@ -0,0 +1,8 @@ + +This option is only valid when used with the option. +This is the default behavior of the option, so you +should never need to specify it, but it is included for the sake of +readability. When this option is specified, the popped state replaces +the current state. + + diff --git a/xmldoc/filters/options/stack-swap.xml b/xmldoc/filters/options/stack-swap.xml new file mode 100644 index 000000000..b96874456 --- /dev/null +++ b/xmldoc/filters/options/stack-swap.xml @@ -0,0 +1,10 @@ + +This is one of three "primary" options to the stack filter. + + +When this option is specified, the current state is swapped with a saved +state from the stack. By default, it is swapped with the top of the stack, +but the can be used to specify a different saved +state. + + diff --git a/xmldoc/filters/options/track-course.xml b/xmldoc/filters/options/track-course.xml new file mode 100644 index 000000000..36b83f29a --- /dev/null +++ b/xmldoc/filters/options/track-course.xml @@ -0,0 +1,10 @@ + +This option computes (or recomputes) a value for the GPS heading at each +trackpoint. This is most useful with trackpoints from formats that don't +support heading information or for trackpoints synthesized by the +interpolate +filter. The heading at each trackpoint is simply the course from the +previous trackpoint in the track. The first trackpoint in each track +is arbitrarily assigned a heading of 0 degrees. + + diff --git a/xmldoc/filters/options/track-fix.xml b/xmldoc/filters/options/track-fix.xml new file mode 100644 index 000000000..4cd9f303a --- /dev/null +++ b/xmldoc/filters/options/track-fix.xml @@ -0,0 +1,9 @@ + +This option sets the GPS fix status for all trackpoints to the specified +value. Valid values for this option are PPS, DGPS, 3D, 2D, or NONE. + + +This option is most useful when converting from a format that doesn't +contain GPS fix status to one that requires it. + + diff --git a/xmldoc/filters/options/track-merge.xml b/xmldoc/filters/options/track-merge.xml new file mode 100644 index 000000000..5ca5bbbf9 --- /dev/null +++ b/xmldoc/filters/options/track-merge.xml @@ -0,0 +1,14 @@ + +This option puts all track points from all tracks into a single track +and sorts them by time stamp. Points with identical time stamps will be +dropped. + + +Merging tracks with the track filter + +Suppose you want to merge tracks recorded with two different GPS devices +at the same time. To do that, use this command line: + +gpsbabel -t -i gpx -f john.gpx -i gpx -f doe.gpx -x track,merge,title="COMBINED LOG" -o gpx -F john_doe.gpx + + diff --git a/xmldoc/filters/options/track-move.xml b/xmldoc/filters/options/track-move.xml new file mode 100644 index 000000000..0641de1e9 --- /dev/null +++ b/xmldoc/filters/options/track-move.xml @@ -0,0 +1,13 @@ + +This option changes the time of all trackpoints. This might be useful if +your track must be moved by one or more hours because of an incorrect +time zone. + + +Time-shifting a track with the track filter + +The following command line will shift all tracks to be one hour later. + +gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx + + diff --git a/xmldoc/filters/options/track-name.xml b/xmldoc/filters/options/track-name.xml new file mode 100644 index 000000000..930b88bf7 --- /dev/null +++ b/xmldoc/filters/options/track-name.xml @@ -0,0 +1,7 @@ + +With the name option you can filter out a track by title. + + +The comparison is always non-case-sensitive. Wildcards are allowed. + + diff --git a/xmldoc/filters/options/track-pack.xml b/xmldoc/filters/options/track-pack.xml new file mode 100644 index 000000000..c65f6893f --- /dev/null +++ b/xmldoc/filters/options/track-pack.xml @@ -0,0 +1,12 @@ + +This option causes all tracks to be appended to one another to form a single +track. This option does not work if any two tracks overlap in time; in that +case, consider using the option. + + +This option is most useful for rejoining tracks that might have +been interrupted by an equipment malfunction or an overnight stop. + + +If no other option is given to the track filter, this option is assumed. + diff --git a/xmldoc/filters/options/track-sdistance.xml b/xmldoc/filters/options/track-sdistance.xml new file mode 100644 index 000000000..7fc4db8f5 --- /dev/null +++ b/xmldoc/filters/options/track-sdistance.xml @@ -0,0 +1,36 @@ + The input track will be split into several tracks + if the distance between successive track points + is greater than the distance given as a parameter. + The distance must be numeric and can be in miles or kilometers, + expressed as one of the character "k", or "m". + If sdistance is given no parameters, this option has the same + effect as the split option without parameters. If there is more + than one track, + use the pack option before before using this. + + For example, to split the track if the distance between + points is greater than 100 meters, use this: + +gpsbabel -t \ + -i gpx -f in.gpx \ + -x track,pack,sdistance=0.1k" \ + -o gpx -F out.gpx + + The sdistance option can be combined with the split option. + The track then will be split only if both time and distance + interval exceeds the supplied values. This technique can be used to + filter out gaps from + the tracklog. The gap is kept only if the gps device is without + signal for longer time than that given and during that time it moves + a distance over that given. + This example splits the track + if the device is without signal for at least 5 minutes + and during this time moves more than 300 meters: + +gpsbabel -t \ + -i gpx -f in.gpx \ + -x track,pack,sdistance=0.3k,split=5m \ + -o gpx -F out.gpx + + + diff --git a/xmldoc/filters/options/track-speed.xml b/xmldoc/filters/options/track-speed.xml new file mode 100644 index 000000000..32d640bdf --- /dev/null +++ b/xmldoc/filters/options/track-speed.xml @@ -0,0 +1,9 @@ + +This option computes a value for the GPS speed at each trackpoint. +This is most useful with trackpoints from formats that don't support +speed information or for trackoints synthesized by the +interpolate +filter. The speed at each trackpoint is the average speed from the +previous trackpoint (distance divided by time). The first trackpoint +in each track is assigned a speed of "unknown." + diff --git a/xmldoc/filters/options/track-split.xml b/xmldoc/filters/options/track-split.xml new file mode 100644 index 000000000..00af234b5 --- /dev/null +++ b/xmldoc/filters/options/track-split.xml @@ -0,0 +1,32 @@ + The input track will be split into several tracks + depending on date of track points. If there is more than one + track, use the pack option before before using this. To + split a single tracks into separate tracks for each day and + name them, use this: + + +gpsbabel -t -i gpx -f in.gpx -x \ + track,split,title="ACTIVE LOG \ + # %Y%m%d" -o gpx -F out.gpx + If the input has multiple tracks, pack them together before +splitting them back apart per day thusly: + +gpsbabel -t -i gpx -f in.gpx \ + -x track,pack,split,title="ACTIVE LOG # %D" \ + -o gpx -F out.gpx + Additionally you can add an interval to the split + option. With this the track will be split if the time + between two points is greater than this parameter. The + interval must be numeric and can be int days, hours, minutes + or seconds, expressed as one of the character "d", "h", "m", + or "s". If no trailing character is present, the units are + assumed to be in seconds. + + For example, to split a track based on an four hour + interval, use this: + +gpsbabel -t \ + -i gpx -f in.gpx \ + -x track,pack,split=4h,title="LOG # %c" \ + -o gpx -F out.gpx + diff --git a/xmldoc/filters/options/track-start.xml b/xmldoc/filters/options/track-start.xml new file mode 100644 index 000000000..9df4086fd --- /dev/null +++ b/xmldoc/filters/options/track-start.xml @@ -0,0 +1,24 @@ + +This option is used along with the to discard +trackpoints that were recorded outside of a specific period of time. +This option specifies the beginning of the time period. + + +If this option is not specified, the time period is assumed to begin at the +dawn of time or January 1, 1970, whichever was later. The time for this +option is expressed in UTC. + + +The value of this option must be in the form of YYYYMMDDHHMMSS, but it is +not necessary to specify the smaller time units if they are not needed. +That is, if you only care about points logged between 10 AM and 6 PM on a +given date, you need not specify the minutes or seconds. + + +Extracting a period of time with the track filter + +To get only the parts of a track that were mapped on 20 July 2005 +between 10 AM and 6 PM, use this command line: + +gpsbabel -t -i gpx -f in.gpx -x track,start=2005072010,stop=2005072018 -o gpx -F out.gpx + diff --git a/xmldoc/filters/options/track-stop.xml b/xmldoc/filters/options/track-stop.xml new file mode 100644 index 000000000..a86755aeb --- /dev/null +++ b/xmldoc/filters/options/track-stop.xml @@ -0,0 +1,15 @@ + +This option is used in conjunction with the option to +discard all trackpoints outside of a given period of time. This option +defines the end of the time period. + + +If this option is not specified, the time period is assumed to end at the +end of civilization as we know it or the year 2038, whichever comes first. +The time for this option is expressed in UTC. + + +See the option for the format of this value and an +example of usage. + + diff --git a/xmldoc/filters/options/track-title.xml b/xmldoc/filters/options/track-title.xml new file mode 100644 index 000000000..be578bd46 --- /dev/null +++ b/xmldoc/filters/options/track-title.xml @@ -0,0 +1,10 @@ + +This option specifies a title for tracks generated by the track filter. +By default, the title of the new track is composed of the start time of +the track appended to this value. + + +If this value contains a percent (%) character, it is treated as a format +string for the POSIX strftime function, allowing custom time-based +track names. + diff --git a/xmldoc/filters/polygon.xml b/xmldoc/filters/polygon.xml new file mode 100644 index 000000000..a193f903e --- /dev/null +++ b/xmldoc/filters/polygon.xml @@ -0,0 +1,78 @@ + +The polygon filter includes points if they are inside +of a polygon. A polygon file looks like an +arc file, except +that the arc it describes must be a closed cycle. That is, +for a simple polygon, the first and last points must be the +same. Here's a square: + + +# A square (not really) polygon +41.0000 -85.0000 +41.0000 -86.0000 +42.0000 -86.0000 +42.0000 -85.0000 +41.0000 -85.0000 + + +Polygons may include islands and holes. To include an +island or a hole, just append it to the main polygon. + + +# A square polygon with a triangular hole +41.0000 -85.0000 +41.0000 -86.0000 +42.0000 -86.0000 +42.0000 -85.0000 +41.0000 -85.0000 +# The hole begins here +41.5000 -85.5000 +41.6000 -85.5000 +41.6000 -85.6000 +41.5000 -85.5000 + + +As with the arc filter, you define a polygon by +giving the name of the file that contains it, using +the option. + + +Note that this filter currently will not work properly +if your polygon contains one or both poles or if it spans the +line of 180 degrees east or west longitude. + + +Using the polygon filter + +Suppose you have a polygon file that defines the border of your county, +called mycounty.txt. This command line will give you only the points +in your county: + +gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt -o mapsend -F 2.wpt + + +Using the polygon and arc filters to find points in or nearly in a +polygon + +Because the polygon and arc filters use +the same file format, you can use them together to find all points that are +"in or nearly in" a polygon. This can be useful if your waypoints or the +boundaries of your polygon are not quite perfect, so you want to provide a +buffer zone around it in case there are points nearby that should be in the +polygon but aren't quite. + + +gpsbabel -i gpx -f points.gpx -x stack,push -x polygon,file=mycounty.txt +-x stack,swap -x arc,file=mycounty.txt,distance=1k -x stack,pop,append +-x duplicate,shortname -o gpx -F nearmycounty.gpx + + +This command makes a copy of the points, finds the ones that are in your +your county, swaps that result with the copy of the original set of points, +finds the ones from that set that are within 1 km of the border of the county, +puts the two lists together, and then filters out any points that appear twice +(This step is necessary because points inside the county but near the county +line will be kept by both the polygon and the arc filter.) + + + diff --git a/xmldoc/filters/position.xml b/xmldoc/filters/position.xml new file mode 100644 index 000000000..13ff374a0 --- /dev/null +++ b/xmldoc/filters/position.xml @@ -0,0 +1,15 @@ + +This filter removes points based on their proximity to each other. A +point is removed if it is within the specified distance of a point that +has come before. + + + +Using the position filter to suppress close points + +The following command removes multiple points that are within +one foot of each other, leaving just one. + +gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f -o mapsend -F 3.wpt + + diff --git a/xmldoc/filters/radius.xml b/xmldoc/filters/radius.xml new file mode 100644 index 000000000..cdc970f40 --- /dev/null +++ b/xmldoc/filters/radius.xml @@ -0,0 +1,17 @@ + +This filter includes or excludes waypoints based on their proximity to a +central point. All waypoints more than the specified distance from the +specified point will be removed from the dataset. + + +By default, all remaining points are sorted so that points closer to the +center appear earlier in the output file. + + + Using the radius filter to find points close to a given point + This example command line would include only points within 1 1/2 miles + of N30.000 W 90.000 + +gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 -o mapsend -F 2.wpt + + diff --git a/xmldoc/filters/reverse.xml b/xmldoc/filters/reverse.xml new file mode 100644 index 000000000..31cfe9062 --- /dev/null +++ b/xmldoc/filters/reverse.xml @@ -0,0 +1,19 @@ + + + The reverse filter is used to reverse tracks and routes. + It's mostly useful for those few formats where track/route + sequence matters and there isn't a way to reverse them using + the program itself. + The reversal is performed in the laziest way possible. + Timestamps are kept with the original waypoints so the + resulting track or route will have the interesting + characteristic that time runs backwards. This tends to make + Magellan Mapsend, in particular, do a wierd thing and place + each waypoint on a separate day. + + Additionally, if you're using this to reverse a route + that navigates, say, an exit ramp or a one way street, you + will be in for unpleasant ride. application cares about + timestamps + + diff --git a/xmldoc/filters/simplify.xml b/xmldoc/filters/simplify.xml new file mode 100644 index 000000000..976f61901 --- /dev/null +++ b/xmldoc/filters/simplify.xml @@ -0,0 +1,21 @@ + +The Simplify filter is used to simplify routes and tracks for use with +formats that limit the number of points they can contain or just to +reduce the complexity of a route. + + +The filter attempts to remove points from each route until the number +of points or the error is within the given bounds, while also attempting +to preserve the shape of the original route as much as possible. + + +The quality of the results will vary depending on the density of points +in the original route and the length of the original route. + + +For example, suppose you have a route from Street Atlas 2003 that you +wish to use with a Magellan GPS receiver that only supports up to 50 points +in a route: + +gpsbabel -r -i saroute -f RoadTrip.anr -x simplify,count=50 -o magellan -F grocery.rte + diff --git a/xmldoc/filters/sort.xml b/xmldoc/filters/sort.xml new file mode 100644 index 000000000..da4ad375e --- /dev/null +++ b/xmldoc/filters/sort.xml @@ -0,0 +1,5 @@ + +This filter sorts waypoints into alphabetical order by the selected field. +You must specify exactly one of the options. + + diff --git a/xmldoc/filters/stack.xml b/xmldoc/filters/stack.xml new file mode 100644 index 000000000..45934ad15 --- /dev/null +++ b/xmldoc/filters/stack.xml @@ -0,0 +1,49 @@ + +This filter is designed to solve advanced problems that involve shuffling +multiple lists of waypoints, tracks, or routes. + + +The stack filter can be used to save the current state of the entire +collection of data. That state is placed on top of a stack of collections, +so you can simultaneously have as many stored collections of data as you +can fit in your computer's memory. + + + The stack filter can be used in conjunction with other + filters to implement a "union" or "logical or" functionality. + The basic idea is to use the stack to store copies of the + original list of waypoints, then use the 'swap' function to + replace each copy with a filtered list. Finally, append all + of the filtered lists to create one big list, which is then + output. The following example finds a list of all points + that are either inside county A or inside county B. Any + points that are inside both counties are duplicated (but the + duplicates can be removed with the DUPLICATE filter; see + above.) + + +gpsbabel -i gpx -f in.gpx \ + -x stack,push,copy \ + -x polygon,file=county_a.txt \ + -x stack,swap \ + -x polygon,file=county_b.txt \ + -x stack,pop,append \ + -o gpx -F out.gpx + + This example reads a large list of waypoints and + extracts the points within 20 miles of each of two cities, + writing the waypoint descriptions into two different PalmDoc + files and exporting all of the points to the GPS receiver: + + +gpsbabel -i gpx -f indiana.gpx \ + -x stack,push,copy \ + -x radius,lat=41.0765,lon=-85.1365,distance=20m \ + -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb \ + -x stack,swap \ + -x radius,lat=39.7733,lon=-86.1433,distance=20m \ + -o palmdoc,dbname=Indianapolis -F indianapolis.pdb \ + -x stack,pop,append \ + -o magellan -F fwaind.wpt + + diff --git a/xmldoc/filters/track.xml b/xmldoc/filters/track.xml new file mode 100644 index 000000000..cf6c39494 --- /dev/null +++ b/xmldoc/filters/track.xml @@ -0,0 +1,8 @@ + +WARNING: This filter always drops empty tracks. + + +This filter performs various operations on track data. + + + diff --git a/xmldoc/filters/transform.xml b/xmldoc/filters/transform.xml new file mode 100644 index 000000000..87a87d2e0 --- /dev/null +++ b/xmldoc/filters/transform.xml @@ -0,0 +1,16 @@ + + This filter can be used to convert GPS data between different data types. + + + Some GPS data formats support only some subset of waypoints, tracks, + and routes. The transform filter allows you to convert between these + types. For example, it can be used to convert a pile of waypoints (such + as those from a CSV file) into a track or vice versa. + + + The following example show you how to create a route from a waypoint table. + gpsbabel -i csv waypts.txt -x transform,rte=wpt -o gpx -F route.gpx + Only the first letter of option value decides which transformation will be done. + Depending on the used option it can be only 'W' for waypoints, 'R' for routes or + 'T' for tracks. + diff --git a/xmldoc/formats/an1.xml b/xmldoc/formats/an1.xml new file mode 100644 index 000000000..9d9a4da01 --- /dev/null +++ b/xmldoc/formats/an1.xml @@ -0,0 +1,15 @@ + +This format supports the DeLorme ".an1" drawing file format. It can +currently be used to either read or write drawing files. If you use +this format to create drawing files with routes or waypoints from another +source, by default it will create "Red Flag" symbols for waypoints, and +thick red lines for routes or tracks. It is possible to merge two drawing +layers by doing something like this: + + +gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1 + + +In this case, the merged data will contain all of the +properties of the original data. + diff --git a/xmldoc/formats/arc.xml b/xmldoc/formats/arc.xml new file mode 100644 index 000000000..a10c27ad1 --- /dev/null +++ b/xmldoc/formats/arc.xml @@ -0,0 +1,6 @@ + +This format is used by GPSBabel itself as the input to the +arc and +polygon filters. See those filters +for more information. + diff --git a/xmldoc/formats/axim_gpb.xml b/xmldoc/formats/axim_gpb.xml new file mode 100644 index 000000000..918ce3c93 --- /dev/null +++ b/xmldoc/formats/axim_gpb.xml @@ -0,0 +1,10 @@ + + This format reads the binary (.gpb) track logs recorded on + Dell Axim Navigation Systems. + + + + This is a read-only format for now as the format was reverse + engineered and there are many unknown bytes. We can successfully + extract the common GPS data. + diff --git a/xmldoc/formats/baroiq.xml b/xmldoc/formats/baroiq.xml new file mode 100644 index 000000000..72c21e4ad --- /dev/null +++ b/xmldoc/formats/baroiq.xml @@ -0,0 +1,5 @@ +Serial download protocol for the Brauniger IQ series of +barograph recording flight instruments. This format creates a +track of altitude vs time which can be merged with a GPS track +of the same flight to create a three dimensional IGC file. + diff --git a/xmldoc/formats/bcr.xml b/xmldoc/formats/bcr.xml new file mode 100644 index 000000000..c5604099d --- /dev/null +++ b/xmldoc/formats/bcr.xml @@ -0,0 +1,21 @@ + +This file format (extension .bcr) is used in Map&Guide +Motorrad Routenplaner 2002 and later versions. +BCR is a route-only format. If you own a newer release (2005 or later) you +may also use the XML export with GPSBabel's tef +input format. + + +There may be other products from Map&Guide that use this format as well. + + +Coordinates are stored in a BCR file in a Mercator projection. The +conversion from the Mercator projection to polar (latitude/longitude) +coordinates and back again may result in visible differences. Experience +reports are welcome. + + + Sample BCR command with all options + gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr + + diff --git a/xmldoc/formats/cambridge.xml b/xmldoc/formats/cambridge.xml new file mode 100644 index 000000000..b2cbda7ac --- /dev/null +++ b/xmldoc/formats/cambridge.xml @@ -0,0 +1,6 @@ + + + + Support for Cambridge/Winpilot flight analysis and planning software for + glider pilots. + diff --git a/xmldoc/formats/cetus.xml b/xmldoc/formats/cetus.xml new file mode 100644 index 000000000..5049acaa3 --- /dev/null +++ b/xmldoc/formats/cetus.xml @@ -0,0 +1,7 @@ + + + + Cetus GPS www.cetusgps.dk is a program for +Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read +and write files for that program. + diff --git a/xmldoc/formats/coastexp.xml b/xmldoc/formats/coastexp.xml new file mode 100644 index 000000000..066e29fcf --- /dev/null +++ b/xmldoc/formats/coastexp.xml @@ -0,0 +1,8 @@ + + + + This is the format used by CoastalExplorer (tm). The +format is XML with items uniquely identified by Windows-style UUIDs. +http://www.rosepointnav.com + + diff --git a/xmldoc/formats/compegps.xml b/xmldoc/formats/compegps.xml new file mode 100644 index 000000000..354b783ea --- /dev/null +++ b/xmldoc/formats/compegps.xml @@ -0,0 +1,14 @@ + +These data files are "character" separated text files like +the pcx format. "Character" means special data lines can have their +own separator. + + +Since release 6.1 of CompeGPS, GPX is also a +supported import/export format for waypoints, routes and tracks. + + +For more information please have a look at +http://www.compegps.com + + diff --git a/xmldoc/formats/copilot.xml b/xmldoc/formats/copilot.xml new file mode 100644 index 000000000..3e0ae98f4 --- /dev/null +++ b/xmldoc/formats/copilot.xml @@ -0,0 +1,14 @@ + + + + This code is mostly intended to convert CoPilot Flight +Planner for Palmd/OS atabases into other formats. You probably should +not use this to write CoPilot databases, although the code is there, +because GPSBabel doesn't convert magnetic declination values. + Questions, bug reports, etc, to ptomblin at +xcski.com + + http://xcski.com/~ptomblin/CoPilot/ +and http://navaid.com/CoPilot + + diff --git a/xmldoc/formats/coto.xml b/xmldoc/formats/coto.xml new file mode 100644 index 000000000..dfe6644fe --- /dev/null +++ b/xmldoc/formats/coto.xml @@ -0,0 +1,20 @@ + +This format supports cotoGPS, a Palm GPS program. +It can read both track and marker (waypoint) files. It is currently unable +to write track files, so only marker files can be written. The marker +categories are written to and read from the icon description. The 'Not +Assigned' category leaves the icon description empty on read. +Currently geocache info is ignored. + + In addition to the documented options, this format also has a +debugging option called which takes an XCSV +delimiter value. It writes some internal values (distance, arc, x and y) +of the cotoGPS track format to the notes field. + + +Contributed by Tobias Minich. + + +cotoGPS + + diff --git a/xmldoc/formats/cst.xml b/xmldoc/formats/cst.xml new file mode 100644 index 000000000..4e8b3df4e --- /dev/null +++ b/xmldoc/formats/cst.xml @@ -0,0 +1,9 @@ + + + + With this format we can read CarteSurTable data files. +CarteSurTable is a shareware program widely used in France. The data +inside have to be seen as a mixture of a waypoints list, one route and +several tracks. phgiraud.free.fr + + diff --git a/xmldoc/formats/csv.xml b/xmldoc/formats/csv.xml new file mode 100644 index 000000000..6b3fc6e7c --- /dev/null +++ b/xmldoc/formats/csv.xml @@ -0,0 +1,12 @@ + + + + There are a billion variants of Comma Separated Value +data. This is the one that makes Delorme S&A Deluxe 9 happy. It's +also a very simple program and useful for many other programs like +spreadsheets. + CSV is also the correct format for Lowrance MapCreate, +their commercial mapping program, or GDM6 (their free waypoint +manager) for iFinder which is available at lowrance.com + + diff --git a/xmldoc/formats/cup.xml b/xmldoc/formats/cup.xml new file mode 100644 index 000000000..487060288 --- /dev/null +++ b/xmldoc/formats/cup.xml @@ -0,0 +1,14 @@ + + This format supports flight analysis data from the + See You + program. + + + Position information is preserved, but the aviation-specific + information such as runway length and airport frequency, are + written as blanks and ignored on read. + + + Tasks are not supported. + + diff --git a/xmldoc/formats/custom.xml b/xmldoc/formats/custom.xml new file mode 100644 index 000000000..fdb1ef7e9 --- /dev/null +++ b/xmldoc/formats/custom.xml @@ -0,0 +1,9 @@ + +This format is not actually used by any real product. It is most useful +for debugging purposes when developing a new format module for GPSBabel. + + +To understand the contents of this file, look at the +style/custom.style file in the GPSBabel source +distribution as well as . + diff --git a/xmldoc/formats/dmtlog.xml b/xmldoc/formats/dmtlog.xml new file mode 100644 index 000000000..44d44bf86 --- /dev/null +++ b/xmldoc/formats/dmtlog.xml @@ -0,0 +1,10 @@ + + This format can be used to convert files from + TrackLogs Digital Mapping. The files + have extension .trl and can contain waypoints and tracks. + + + We have seen three different types of this format. Two are binary + and one is an XML based format. All three types are supported + by our reader. + diff --git a/xmldoc/formats/dna.xml b/xmldoc/formats/dna.xml new file mode 100644 index 000000000..8e12bb670 --- /dev/null +++ b/xmldoc/formats/dna.xml @@ -0,0 +1,8 @@ + + + + Navitrak DNA marker format - Another CSV format file. This +is the format that is compatible with the DNA Desktop import/export +command. Reading the binary Markers.jwp format directly off the data +card is not supported yet. Contributed by Tim Zickus. + diff --git a/xmldoc/formats/easygps.xml b/xmldoc/formats/easygps.xml new file mode 100644 index 000000000..509a94c75 --- /dev/null +++ b/xmldoc/formats/easygps.xml @@ -0,0 +1,15 @@ + + + + This is the binary file format used by EasyGPS. This +format is seemingly being phased out in favor of GPX in newer versions +of EasyGPS, but this allows conversions to and from the old binary +.loc format. + + + http://www.easygps.com/ + + Information about and sketchy code to implement this file +format were provided by Eric Cloninger. + + diff --git a/xmldoc/formats/fugawi.xml b/xmldoc/formats/fugawi.xml new file mode 100644 index 000000000..d507f2765 --- /dev/null +++ b/xmldoc/formats/fugawi.xml @@ -0,0 +1,27 @@ + + + + This was a requested CSV format, *not* the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel +cannot read tracks in this format, but converting a track into it and +then importing as track in Fugawi works. + It is known to work with Fugawi V3.1.4.635. When +importing/exporting waypoints, one has to specify the order of fields +as follows (names of fields may depend on the language used by +Fugawi): + + - Name + - Comment + - Description + - Latidude + - Longitude + - Altitude (metres) + - Date (yyyymmdd/yymmdd) + - Time of day (hhmmss) + + When importing tracks, use "[ignore]" instead of "Name", +"Comment" and "Description". + + http://www.fugawi.com/ + + diff --git a/xmldoc/formats/garmin.xml b/xmldoc/formats/garmin.xml new file mode 100644 index 000000000..b72031f94 --- /dev/null +++ b/xmldoc/formats/garmin.xml @@ -0,0 +1,166 @@ + + GPSBabel supports a wide variety of Garmin hardware via serial + on most operating systems and USB on Windows, Linux, and OS X. + + + + For serial models, be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. + + + + Supported models on USB include + +Edge 205 +Edge 305 +eTrex Legend C +eTrex LegendCX +eTrex Venture C +eTrex Venture CX +eTrex VistaC +eTrex Vista CX +Forerunner 205 +Forerunner 301 +Forerunner 305 +Foretrex 201 +Foretrex 301 +GPSMAP 195 +GPSMAP 276C +GPSMAP 295 +GPSMAP 296C +GPSMAP 378 +GPSMAP 396 +GPSMAP 478 +GPSMAP 496 +GPSMAP 60C +GPSMAP 60CS +GPSMAP 60CSX +GPSMAP 60CX +GPSMAP 76C +GPSMAP 76CS +GPSMAP 76CSX +GPSMAP 76CX +GPSMAP 96 +GPSMAP 96C +Nuvi 300This unit uses GPX format, not Garmin protocol. Therefore one should communicate with it by reading and writing GPX files instead of using this format. +Nuvi 310 +Nuvi 350 +Nuvi 360 +Quest +Quest II +StreetPilot 2610 +StreetPilot 2620 +StreetPilot 2650 +StreetPilot 2720 +StreetPilot 2730 +StreetPilot 2820 +StreetPilot 7200 +StreetPilot 7500 +StreetPilot c310 +StreetPilot c320 +StreetPilot c330 +StreetPilot c340 +StreetPilot c510 +StreetPilot c530 +StreetPilot c550 +StreetPilot i2 +StreetPilot i3 +StreetPilot i5 + + + +and most serial units including: + +eMap +eTrex Camo +eTrex Legend +eTrex Summit +eTrex Venture +eTrex Vista +eTrex Yellow +Forerunner 201 +Foretrex 201 +Geko 201 +Geko 301 +GPS 12CX +GPS 12Map +GPS 12 +GPS 12XL +GPS III +GPS III+ +GPS II +GPS II+ +GPS V +StreetPilot III +StreetPilot III+ + + + + + None of the GPSBabel developers has access to every model on that + list, but we've received reports of success and/or have reasonable + expectations that the above models work. If you succeed with + a model that is not on that list, please send a message to the + gpsbabel-misc mailing list with the details so that we may add it. + + + + Not every feature on every model is supported. For example, + while we do extract data such as heart rate and temperature from + tracks on the sporting models like Edge and Forerunner, GPSBabel + is not a fitness program at its core and does not support features + like courses or calorie/fitness zone data. + + + + To communicate with a unit serially, use the name of that + serial port such as "COM1" or "/dev/cu.serial". + + + To communicate via USB use "usb:" as the filename on all OSes. + Thus, to read the waypoints from a Garmin USB unit and write + them to a GPX file: + + gpsbabel -i garmin -f usb: -o gpx -F blah.gpx + + + + If you have multiple units attached via USB, you may provide + a unit number, with zero being the implied default. So if you + have three USB models on your system, they can be addressed as + "usb:0", "usb:1", and "usb:2". To get a list of recognized devices, + specifiy a negative number such as: + + gpsbabel -i garmin -f usb:-1 + + +When reporting problems with the Garmin format, be sure to include +the full unit model, firmware version, and be prepared to offer +debugging dumps by adding "-D9" to the command line, like: + + + gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx + + +Custom icons are supported on units that support that. +Neither GPSBabel nor your firmware know what is associated with any +given slot number. They don't know that the picture you placed in the +first slot is a happy face, they only know they're in the lowest +numbered slot. GPSBabel names the them consistently with Mapsource, +so they are named 'Custom 0' through 'Custom 511'. + + + For models where the connection on the GPS is a serial interface, + be sure the GPS is set for "Garmin + mode" in setup and that nothing else (PDA hotsync programs, gpsd, + getty, pppd, etc.) is using the serial port. + + + For models connected via USB, we recommend use of the 'usb:' + filename. For this to work on Windows, you must install + the Garmin driver. For Linux, this will fail if have the garmin_gps + kernel module loaded. + See the Operating System Notes for details. + + diff --git a/xmldoc/formats/garmin301.xml b/xmldoc/formats/garmin301.xml new file mode 100644 index 000000000..3887fe681 --- /dev/null +++ b/xmldoc/formats/garmin301.xml @@ -0,0 +1,8 @@ + + + This is a very simple format that +is most useful for exporting data from a Garmin301 to other programs +for analysis. It's a simple comma delimited format that includes the +timestamp, 3D position information and heart rate so you can pull it +into a spreadsheet or graphing program. + diff --git a/xmldoc/formats/garmin_poi.xml b/xmldoc/formats/garmin_poi.xml new file mode 100644 index 000000000..dcf877cf7 --- /dev/null +++ b/xmldoc/formats/garmin_poi.xml @@ -0,0 +1,9 @@ + + + + The Garmin POI loader +loads custom points of interest into certain models of +Garmin GPS receivers. (As of this writing, only the models introduced +in 2005 and later are supported. See Garmin's site for more info.) +This is the format readable that that program. + diff --git a/xmldoc/formats/garmin_txt.xml b/xmldoc/formats/garmin_txt.xml new file mode 100644 index 000000000..868a97540 --- /dev/null +++ b/xmldoc/formats/garmin_txt.xml @@ -0,0 +1,23 @@ + +This is a textual format that contains nearly all of the information +contained in the MapSource main format, GDB. +This format also contains some computed values such as distances between +routepoints and trackpoints, speed, and course (heading). + + +The main goal of garmin_txt is to make aviation data more available. Because +MapSource supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource. + + +During the export with MapSource, some fields are written using local settings +of MapSource and Windows. These include grid format, gps datum, distance and +temperature units, and the representation of date and time fields. GPSBabel +tries to read all items automatically. Problems with date and time format can +be solved with the 'date' and 'time' options. + + + Command showing garmin_txt output with all options + gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" -f in.txt -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 -F out.txt + + diff --git a/xmldoc/formats/gcdb.xml b/xmldoc/formats/gcdb.xml new file mode 100644 index 000000000..c01e0c721 --- /dev/null +++ b/xmldoc/formats/gcdb.xml @@ -0,0 +1,7 @@ + + + + This is the GeocachingDB by DougsBrat. It works with v2 +and v3 of this program. See vip.hyperusa.com + + diff --git a/xmldoc/formats/gdb.xml b/xmldoc/formats/gdb.xml new file mode 100644 index 000000000..eb25c0b8b --- /dev/null +++ b/xmldoc/formats/gdb.xml @@ -0,0 +1,11 @@ + +Support for the "Garmin GPS Database" format used by +default in MapSource versions since release 6.0. By default GPSBabel creates +gdb files of version 2. Version 2 is used in Mapsource 6.3 and 6.5. + + +Garmin GPS database is an undocumented file format. The +basic info for this module came from the existing MapSource +conversion code. + + diff --git a/xmldoc/formats/geo.xml b/xmldoc/formats/geo.xml new file mode 100644 index 000000000..7cd659e09 --- /dev/null +++ b/xmldoc/formats/geo.xml @@ -0,0 +1,11 @@ + +This format supports the Geocaching.com/EasyGPS ".loc" format. This format +was created specifically for Geocaching.com and is not the same as the +standard EasyGPS .loc format. See the EasyGPS +or GPX formats for more general EasyGPS support. + + +This is a simple XML-based format containing only very basic information +about geocaches. If you can use the GPX +format instead, you should consider doing so as it is a much richer format. + diff --git a/xmldoc/formats/geonet.xml b/xmldoc/formats/geonet.xml new file mode 100644 index 000000000..44e255ed8 --- /dev/null +++ b/xmldoc/formats/geonet.xml @@ -0,0 +1,8 @@ + + + + Input support for the GEOnet Names Server (GNS) country +file structure. Export to this format is not possible, as this format +has too many fields that we never get populated by any other +format. + diff --git a/xmldoc/formats/geoniche.xml b/xmldoc/formats/geoniche.xml new file mode 100644 index 000000000..8ace298c3 --- /dev/null +++ b/xmldoc/formats/geoniche.xml @@ -0,0 +1,8 @@ + + + + Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. See +nwlink.com + + diff --git a/xmldoc/formats/glogbook.xml b/xmldoc/formats/glogbook.xml new file mode 100644 index 000000000..c79db28f6 --- /dev/null +++ b/xmldoc/formats/glogbook.xml @@ -0,0 +1,7 @@ + + + + This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. http://www.garmin.com + + diff --git a/xmldoc/formats/google.xml b/xmldoc/formats/google.xml new file mode 100644 index 000000000..f564951ae --- /dev/null +++ b/xmldoc/formats/google.xml @@ -0,0 +1,36 @@ + + + + This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Maps route URL (use +the "link to this page" option to get a usable URL.) This allows you +to plan a route using Google Maps, then download it and use it in your +own mapping program or GPS receiver. To get a file suitable for use +with GPSBabel, plan your route as usual with Google Maps. Once you've +got it the way you want it, click the "Link to this page" link in the +upper right-hand corner of the Google Maps page. Then, edit the URL +that appears in your address bar by adding "&output=js" (without +the quotes) onto the end. Hit enter, and the resulting page will be +mostly empty. It doesn't look like much, but it contains exactly what +GPSBabel needs. Save it to disk using whatever menu option your web +browser provides. + + +Note that if you are using Microsoft Internet Explorer, you should make sure +to save the web page as "Web Page, HTML Only". If you save it as "Web Page, +Complete", it will be reformatted into a non-XHTML format that GPSBabel +cannot read. + + +If you use a Unix-compatible +operating system, this shell script might be useful: + + +#!/bin/sh +FROM="233 S. Upper Wacker Dr, Chicago, IL" +TO="1060 W. Addison St, Chicago, IL" +wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \ +2&>/dev/null >google_map.js +gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx + + diff --git a/xmldoc/formats/gpilots.xml b/xmldoc/formats/gpilots.xml new file mode 100644 index 000000000..c3c9dd450 --- /dev/null +++ b/xmldoc/formats/gpilots.xml @@ -0,0 +1,12 @@ + + + + This is a Palm/OS file format for GPilotS. It was tested +against version 6.2. + + + http://www.cru.fr/perso/cc/GPilotS/ + + Neither tracks nor routes are supported at this +time. + diff --git a/xmldoc/formats/gpl.xml b/xmldoc/formats/gpl.xml new file mode 100644 index 000000000..cace2eaa4 --- /dev/null +++ b/xmldoc/formats/gpl.xml @@ -0,0 +1,8 @@ + + + + This is the 'gpl' format as used in Delorme mapping +products. It is a track format and contains little more than the +tracklog of a GPS that was attached while driving. frontiernet.net + + diff --git a/xmldoc/formats/gpsdrive.xml b/xmldoc/formats/gpsdrive.xml new file mode 100644 index 000000000..5cb72f0af --- /dev/null +++ b/xmldoc/formats/gpsdrive.xml @@ -0,0 +1,7 @@ + + + + GpsDrive way.txt file format. A space seperated format +file. Tested against GpsDrive v 1.30 found at kraftvoll.at. +Contributed by Alan Curry. + diff --git a/xmldoc/formats/gpsdrivetrack.xml b/xmldoc/formats/gpsdrivetrack.xml new file mode 100644 index 000000000..dc127adc6 --- /dev/null +++ b/xmldoc/formats/gpsdrivetrack.xml @@ -0,0 +1,7 @@ + + + + Format used by GpsDrive to save tracks. Like GPSDRIVE a +space seperated format file. See above for a link to GpsDrive. +Contributed by Tobias Minich. + diff --git a/xmldoc/formats/gpsman.xml b/xmldoc/formats/gpsman.xml new file mode 100644 index 000000000..b1b0a6ede --- /dev/null +++ b/xmldoc/formats/gpsman.xml @@ -0,0 +1,13 @@ + + + + GPS Manager +can read and write formats GPSBabel doesn't understand. The format defaults +(WGS84, DDD) work reliably. Tracks, routes, and non-default format options +are not supported. + + + This format is documented at the GPS Manager + doc site. + + diff --git a/xmldoc/formats/gpspilot.xml b/xmldoc/formats/gpspilot.xml new file mode 100644 index 000000000..26ab9000b --- /dev/null +++ b/xmldoc/formats/gpspilot.xml @@ -0,0 +1,10 @@ + + + + The file format for GPSPILOT gpspilot.com was provided by Ron +Parker. The output from this module has been tested with GPSPilot +Tracker v5.05sx, but it is based on reverse-engineering so it may not +work with all versions of all GPSPilot products. It had read-only +support for Airport, Navaid, City and Landmark files but will read and +write Point files. + diff --git a/xmldoc/formats/gpssim.xml b/xmldoc/formats/gpssim.xml new file mode 100644 index 000000000..c318310ff --- /dev/null +++ b/xmldoc/formats/gpssim.xml @@ -0,0 +1,9 @@ + + This is a write-only format used to feed waypoints, tracks, and routes + into Franson Technolgies' + GpsGate simulator. + + + To use these files in GpsGate, select 'Simulator' and then + "File->Open". + diff --git a/xmldoc/formats/gpsutil.xml b/xmldoc/formats/gpsutil.xml new file mode 100644 index 000000000..52f2f9237 --- /dev/null +++ b/xmldoc/formats/gpsutil.xml @@ -0,0 +1,8 @@ + + + + GPSUtil has a simple file format of this program that runs +on POSIX- compliant OSes like UNIX and Linux. Reads and writes of +this format are reliable. (I've also contributed to this program.) +It's available at cs.uakron.edu. + diff --git a/xmldoc/formats/gpx.xml b/xmldoc/formats/gpx.xml new file mode 100644 index 000000000..1af5de8d9 --- /dev/null +++ b/xmldoc/formats/gpx.xml @@ -0,0 +1,9 @@ + + + + This is the most capable and expressive of all the file +formats supplied. It is described at topografix.com and is +supported by EasyGPS, ExpertGPS, and many other programs described at +topografix.com + + diff --git a/xmldoc/formats/gtm.xml b/xmldoc/formats/gtm.xml new file mode 100644 index 000000000..8b28f36e4 --- /dev/null +++ b/xmldoc/formats/gtm.xml @@ -0,0 +1,5 @@ + Input and output support for waypoints, tracks and routes in + the GPS TrackMaker + binary format. + Code implemented by Gustavo Niemeyer. + diff --git a/xmldoc/formats/gtrnctr.xml b/xmldoc/formats/gtrnctr.xml new file mode 100644 index 000000000..f59087135 --- /dev/null +++ b/xmldoc/formats/gtrnctr.xml @@ -0,0 +1,17 @@ + +Garmin Training Center is the successor to Garmin' Logbook program +for their workout units. It is a free upgrade. + + +This format is somewhat underachieving in GPSBabel. It is a write-only +format; we never read it. The bigger problem, however, is a fundamental +impedance mismatch between this format and most of what we support. GPSBabel +fundamentally deals in waypoints, tracks, and routes. While we do record +things like heart rate and temperature when we know it, the fundamentals +of Training Center are different - it deals in concepts like laps and calories +which are rather alien to GPSBabel and most of the formats we support. As +such, while we can describe the tracks pretty accurately, things like +calories and heart zone tracking are not supported. + + + diff --git a/xmldoc/formats/hiketech.xml b/xmldoc/formats/hiketech.xml new file mode 100644 index 000000000..65d69bf7d --- /dev/null +++ b/xmldoc/formats/hiketech.xml @@ -0,0 +1,8 @@ + + + + This is the .gps format used by the Mac OS X applications +written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. +More information about these products can be found at hiketech.com + + diff --git a/xmldoc/formats/holux.xml b/xmldoc/formats/holux.xml new file mode 100644 index 000000000..be227fb38 --- /dev/null +++ b/xmldoc/formats/holux.xml @@ -0,0 +1,28 @@ + + + + The Holuxgm-100 (e-fox) gps receiver uses standard +compact flash cards. File formats were provided by Holux-Taiwan +holux.com to the author. +The code was tested against version 2.27E1; other versions and +receivers may work but have not been explictly tested. Anyone with +information on other Holux receivers is encouraged to contact +jochen@bauerbahn.net. + + When copying the .wpo file to a flash card, the file must +be named tempwprt.wpo as the +receiver will ignore all other files. + + Comparing the waypoints of a .wpo files against other +formats like .gpx you may notice a small difference in the latitude +and longitude values. The reason is the low resolution of the +coordinates in the wpo file format. In a .wpo file the reolution is +1/10"; in gpx for example it is 1/100". A a practical matter, this +loss is only about 1.7 meters (5 feet). + + The generated waypoint failes can also be used by MapShow +version 1.14. This program is free of charge from the Holux web site. + + This format was contributed by Jochen Becker. + + diff --git a/xmldoc/formats/hsandv.xml b/xmldoc/formats/hsandv.xml new file mode 100644 index 000000000..88847d68c --- /dev/null +++ b/xmldoc/formats/hsandv.xml @@ -0,0 +1,8 @@ + + + + HSA Systems Endeavour Navigator format - will import both +the old version 4.x binary files, and the newer XML based ones. Only +writes the new XML (5.0 and above) format. (use the .exp +extension) + diff --git a/xmldoc/formats/html.xml b/xmldoc/formats/html.xml new file mode 100644 index 000000000..da0de56a7 --- /dev/null +++ b/xmldoc/formats/html.xml @@ -0,0 +1,11 @@ + HTML output generates a single HTML file of all of the +waypoints in the input file. It supports a number of Groundspeak GPX +extensions, as well as filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. + + The following command line reads a GPX file with +Groundspeak extensions and writes an HTML file with encrypted hints +that is rendered using a custom stylesheet: + +gpsbabel -i gpx -f 12345.gpx -o html,stylesheet=green.css,encrypt -F 12345.html + diff --git a/xmldoc/formats/igc.xml b/xmldoc/formats/igc.xml new file mode 100644 index 000000000..0c1485b6e --- /dev/null +++ b/xmldoc/formats/igc.xml @@ -0,0 +1,134 @@ + +FAI/IGC Data File -- Used by the international gliding +community to record gliding flights. IGC files can be converted to +and from tracks representing recorded flights, and routes representing +task declarations in other formats. + + +
              +IGC Data Format Notes + +Refer to Appendix 1 of +http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp +for the specification of the IGC data format. + + +A sample list of software applications that use data in IGC format can be +found at +http://www.fai.org:81/gliding/gnss/gnss_analysis_software.pdf + + +GPSBabel can be used to translate data in IGC format to and from various other +formats. + + +Routes in other formats are used to represent IGC task declarations. + + +Tracks in other formats are used to represent IGC recorded flights. + +
              + +
              +Converting to IGC format + +IGC files generated by GPSBabel will NOT pass security validation tests since +the data they contain cannot be proven to originate from an approved flight +recorder. For most software applications that use IGC files this is not an +issue but for competition scoring, record and badge claims the generated files +will not be accepted as proof of a flight. + + +A track stored in another format (GPX for example) representing a recorded +flight can be converted into an IGC file: + +gpsbabel -i gpx -f mytrk.gpx -o igc -F myflight.igc + +If multiple track segments are provided in the input file, the one with the +most points will be used. + + +A route stored in another format representing a task declaration can be +converted into an IGC file: + +gpsbabel -i gpx -f myrte.gpx -o igc -F mytask.igc + +A route and a track in other formats can be included into a single IGC file: + +gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -o igc -F myflight.igc + +A similar result can be obtained by downloading the track log and routes +directly from a GPS device connected to a PC. For example to create an IGC +file from data recorded in a Garmin GPS connected to the first serial port of +a PC running Linux: + +gpsbabel -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc + +For Windows operating systems: + +gpsbabel -t -r -i garmin -f com1 -o igc -F myflight.igc + +A waypoint file in another format containing a waypoint whose short name is +"PILOT" can be merged into an IGC file. The description field of the waypoint +will be used for the pilot name in the IGC file header: + +gpsbabel -i gpx -f mytrk.gpx -f myrte.gpx -f mywpt.gpx -o igc -F myflight.igc +gpsbabel -w -t -r -i garmin -f /dev/ttyS0 -o igc -F myflight.igc + +Some formats such as GPX allow routes, tracks and waypoints to exist in the +same file and can be used to fully populate an IGC file: + +gpsbabel -i gpx -f myall.gpx -o igc -F myflight.igc +
              + +
              +Converting from IGC format + +Data in an IGC file can be converted into other formats. For example to +generate OziExplorer files containing tracks representing the recorded +flight (myozi.plt) and routes representing declared tasks (myozi.rte): + +gpsbabel -i igc -f myflight.igc -o ozi -F myozi + +Or to GPX format: + +gpsbabel -i igc -f myflight.igc -o gpx -F myflight.gpx + +Header information from the IGC file will be written to the description field +of the track(s). + + +If both pressure altitude and GNSS altitude are recorded in the IGC file, two +tracks will be written to the new track file, representing the two altitude +tracks. The latitude, longitude and timestamps in the tracks will be identical. + +
              + +
              +Merging into IGC format + +A route stored in another format can be merged with an existing IGC file that +has no task declaration, to generate a new IGC file with a task declaration: + +gpsbabel -i igc -f myflight.igc -i gpx -f myrte.gpx -o igc -F mynew.igc + +A two dimensional (lat/lon) track recorded during a flight by a GPS receiver +can be merged with a one dimensional (altitude) track recorded during the same +flight by a barograph instrument. The result is a three dimensional IGC file +representing the flight: + +gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc -F my3D.igc + +The same can be acheived by downloading directly from a barograph instrument +supported by GPSBabel. For example with a Brauniger IQ Comp GPS variometer: + +gpsbabel -i baroiq -f /dev/ttyS0 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + +or: + +gpsbabel -i baroiq -f com1 -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + +(Documentation contributed by Chris Jones, Aug 2004) + +
              + diff --git a/xmldoc/formats/ignrando.xml b/xmldoc/formats/ignrando.xml new file mode 100644 index 000000000..aedde6626 --- /dev/null +++ b/xmldoc/formats/ignrando.xml @@ -0,0 +1,6 @@ + +This format supports IGN Rando track files. IGN Rando is a program mainly +used in France for Topo maps. The files are XML based and are "windows-1252" +encoded. Trackpoints do not have time stamps. + + diff --git a/xmldoc/formats/kml.xml b/xmldoc/formats/kml.xml new file mode 100644 index 000000000..a77c7238c --- /dev/null +++ b/xmldoc/formats/kml.xml @@ -0,0 +1,10 @@ + +KML, the Keyhole Markup Language, is used by Keyhole and +Google Earth. There are features in this file format that GPSBabel +doesn't support - such as camera views - but waypoints, tracks, and routes +work well. + + +Google Earth also uses GPSBabel internally for receiver communications +and several file format imports and exports. + diff --git a/xmldoc/formats/ktf2.xml b/xmldoc/formats/ktf2.xml new file mode 100644 index 000000000..2ace12f66 --- /dev/null +++ b/xmldoc/formats/ktf2.xml @@ -0,0 +1,5 @@ + + + + Support for Kartex 5 trackfiles. For more info see kwf2. + diff --git a/xmldoc/formats/kwf2.xml b/xmldoc/formats/kwf2.xml new file mode 100644 index 000000000..307caa1ff --- /dev/null +++ b/xmldoc/formats/kwf2.xml @@ -0,0 +1,9 @@ + + + + Support for Kartex 5 waypoint files. Kartex is a Swedish + map and GPS positioning system. GPSBabel can read and write + files from Kartex 4 and 5 with WGS84 coordinates. UTM or + Swedish grid are not supported. + + diff --git a/xmldoc/formats/lowranceusr.xml b/xmldoc/formats/lowranceusr.xml new file mode 100644 index 000000000..79a34410a --- /dev/null +++ b/xmldoc/formats/lowranceusr.xml @@ -0,0 +1,9 @@ + +The Lowrance iFinder GPS series has the unique capability +to output its data to an MMC card. The data is saved to the card as a +.USR file and can be read by your computer using a card reader. +Waypoints, routes, tracks are supported. By default, Event marker +icons are converted to waypoints. Symbols tend to get lost in the +translation. + + diff --git a/xmldoc/formats/mag_pdb.xml b/xmldoc/formats/mag_pdb.xml new file mode 100644 index 000000000..eff15549d --- /dev/null +++ b/xmldoc/formats/mag_pdb.xml @@ -0,0 +1,10 @@ + + + + With this format we support the Palm/OS export for +Map&Guide based products like "PowerRoute", +"Motorrad-Routenplaner" and (maybe) other software. The exported files +can contain maps and/or route descriptions. The reader for this format +has been tested with PowerRoute 5+6, Motorrad-Routenplaner +2002(-2006). + diff --git a/xmldoc/formats/magellan.xml b/xmldoc/formats/magellan.xml new file mode 100644 index 000000000..bc671532e --- /dev/null +++ b/xmldoc/formats/magellan.xml @@ -0,0 +1,37 @@ +GPSBabel supports the following Magellan receivers: + + 310 + 315 + Map330 + SporTrak Map Color + SporTrak Map + SporTrak Map Pro + SporTrak Map Topo + Meridian (green or yellow) + Meridian Gold + Meridian Platinum + Meridian Color + Explorist 100 (with aftermarket cable) + Explorist 200 (with aftermarket cable) + Explorist 300 (with aftermarket cable) + Explorist 210 + Explorist 300 + Explorist 400 + Explorist 500 + Explorist 600 + Explorist XL + + + + + This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, 400, 500, 600, XL) or on removable memory. + + + If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. + diff --git a/xmldoc/formats/magellan1.xml b/xmldoc/formats/magellan1.xml new file mode 100644 index 000000000..2ee5fbf23 --- /dev/null +++ b/xmldoc/formats/magellan1.xml @@ -0,0 +1,40 @@ +GPSBabel supports the following Magellan receivers: + + 310 + 315 + Map330 + SporTrak Map Color + SporTrak Map + SporTrak Map Pro + SporTrak Map Topo + Meridian (green or yellow) + Meridian Gold + Meridian Platinum + Meridian Color + Explorist 100 (with aftermarket cable) + Explorist 200 (with aftermarket cable) + Explorist 300 (with aftermarket cable) + Explorist 210 + Explorist 300 + Explorist 400 + Explorist 500 + Explorist 600 + Explorist XL + + + +The RoadMate family of products is not supported. + + + + This format is used for both the serial protocol used on the + devices with serial ports such as Map330 and Meridian and for + the files stored either in either the unit's internal memory + (Explorist 210, 400, 500, 600, XL) or on removable memory. + + + If you specify a serial port for the file (.e.g. "COM1", "/dev/ttyS0") + to be read or written, GPSBabel will use serial protocol. Specifying + a file, either on local filesystem or on a mounted flash card reader, + will results in the file-based format being used. + diff --git a/xmldoc/formats/magellanx.xml b/xmldoc/formats/magellanx.xml new file mode 100644 index 000000000..be4fa14a9 --- /dev/null +++ b/xmldoc/formats/magellanx.xml @@ -0,0 +1,14 @@ + + This is the SD card format used by the Magellan Explorist 400, + 500, 600, and XL and internally on those devices plus the + Explorist 210. Waypoints are identical to the Magellan SD format + used by Meridian, but allows longer waypoint names. Routes are + subtly different. + + + You should name any file containing waypoints created with + this format with a ".upt" extension so the firmware can read it. + Similarly, routes should be named ".rte" and tracks should be + named ".log". + + diff --git a/xmldoc/formats/maggeo.xml b/xmldoc/formats/maggeo.xml new file mode 100644 index 000000000..506567d13 --- /dev/null +++ b/xmldoc/formats/maggeo.xml @@ -0,0 +1,11 @@ + + + + The SD card format used by the Magellan Explorist 400, +500, and 600 to describe geocaches. Notice what while the format can +hold an infinite number of geocaches, the unit will read and silently +discard all but 200 geocache POIs at a time. + You should name any file created with this format with a +".gs" extension so the firmware can read it. + + diff --git a/xmldoc/formats/magnav.xml b/xmldoc/formats/magnav.xml new file mode 100644 index 000000000..a06a0490e --- /dev/null +++ b/xmldoc/formats/magnav.xml @@ -0,0 +1,44 @@ + +Magellan NAV Companion for Palm/OS is not really designed +for this sort of use, but its file format is supported and with a +little bit of patience you can both read and write NAV Companion +waypoints. This conversion is based on +partially incomplete reverse-engineering of the record format, so it +may not work with all versions of NAV Companion. It has been tested +with version 2.10 and 3.20. + + +Translating NAV Companion waypoints to another format is as easy +as with any other format. Just find the Companion_Waypoints database +in your palm backup directory and use it as the input file. + + +When translating waypoints back to NAV Companion, though, you need +to jump through some hoops: + + +First, you must merge any waypoints that already exist in the database +in your Palm Backup directory with the ones you are adding; failure to +do so will result in only the new points being available in NAV Companion, +even if you give the new database a different name (it will overwrite +the old database, even in your backup directory. That's a feature of +PalmOS, not of NAV Companion.) + + +To merge the databases, use a command line like the following: + +gpsbabel -i magnav -f Companion_Waypoints.PDB -i geo -f geocaching.loc -o magnav -F merged.pdb + +Second, you must use the installer to install your new PDB file. Don't +make the mistake of copying it over the existing Companion_Waypoints.PDB +file; the one on the handheld will overwrite it rather than merging with +it. + + +Finally, because NAV Companion is not designed to work with desktop +applications, you must tell NAV Companion that its waypoints database +has changed out from under it. One way to do this is to go to the +waypoints screen and attempt to scroll; that will force it to reread +the database and fix the record pointers that it keeps on the heap. + + diff --git a/xmldoc/formats/mapconverter.xml b/xmldoc/formats/mapconverter.xml new file mode 100644 index 000000000..1ab390cea --- /dev/null +++ b/xmldoc/formats/mapconverter.xml @@ -0,0 +1,61 @@ + +Mapconverter is a format that is read by Mapopolis.com's +mapconverter application. + + +Mapconverter is an application used to create userland maps and map data for +Mapopolis.com's Mapopolis program. The mapconverter format is essentially +waypoint data prepared in a format that the mapconverter application will +accept. + + +The steps for using GPSBabel and Mapconverter go something like this: + + +Step 1: Create a mapconverter file using gpsbabel. + +gpsbabel -i geo -f geocaching.loc -o mapconverter -F foo.txt + +Step 2: Launch mapconverter.exe and choose foo.txt as your input file. + Click the begin button to have mapconverter process foo.txt. + + +If all goes successfully, you should have a file called "foo.pdb" ready +for syncing with your PDA. Put it wherever Mapopolis thinks it should be +on your PDA. + +
              +Notes + + + +GPSBabel will write the name of its own output file in the output file + it creates as the input for Mapconverter. Mapconverter will replace + the extension of this filename with ".pdb". + + + + +The PocketPC version of Mapopolis doesn't notice files with the ".pdb" + extension. To make this work, change the extension to ".mlp" when + copying the mapconverter output to your PocketPC PDA. + + + + +Mapconverter only works with Mapopolis version 3.x. Mapopolis version + 4 will refuse to load mapconverter maps. There is no known work-around + for this at the time of this writing. + + + + +Mapconverter is no longer available from the Mapopolis website. If you + need a copy of mapconverter, ask on your local GPS Software discussion + forum and I'm sure someone will have it. As far as I know, It was never + actually acknowledged/supported by Mapopolis to begin with. + + + +
              + diff --git a/xmldoc/formats/mapsend.xml b/xmldoc/formats/mapsend.xml new file mode 100644 index 000000000..0dc62d684 --- /dev/null +++ b/xmldoc/formats/mapsend.xml @@ -0,0 +1,8 @@ + +This format supports the Magellan MapSend native +file format. + + +Kudos to Magellan for having the foresight to document their file formats, +making software like this possible. + diff --git a/xmldoc/formats/mapsource.xml b/xmldoc/formats/mapsource.xml new file mode 100644 index 000000000..7460e008b --- /dev/null +++ b/xmldoc/formats/mapsource.xml @@ -0,0 +1,28 @@ + +This format supports the Garmin Mapsource +product family. + + +This format is based on significant reverse-engineering and guesswork. +GPSBabel's output appears to be compatible with the various versions of +MapSource. Icon mapping is attempted between different MapSource versions. +Altitude is supported, but proximity and depth are not. + + +Naming files *.mps will allow file->open in Mapsource to find the files +more easily. + + +Versions 3, 4, and 5 of the Mapsource data format are handled automatically +on input. By default the output is version 5. (Until 3/2004, it was +version 3, but since Mapsource updates are free, the convenience of +having modern icon sets outweighs the backward compatibility concern. +Users of other versions can either upgrade or specify the switches to +get output in a compatible format.) Waypoints, routes, and tracklogs are +all handled, but map sets are ignored. + + +Information on the Garmin Mapsource format was provided by Ian Cowley and +Mark Bradley. The code was implemented by Robert Lipe and Mark Bradley. + + diff --git a/xmldoc/formats/msroute.xml b/xmldoc/formats/msroute.xml new file mode 100644 index 000000000..699384c5b --- /dev/null +++ b/xmldoc/formats/msroute.xml @@ -0,0 +1,20 @@ + + + + Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported. + Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions. + One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. + + diff --git a/xmldoc/formats/msroute1.xml b/xmldoc/formats/msroute1.xml new file mode 100644 index 000000000..699384c5b --- /dev/null +++ b/xmldoc/formats/msroute1.xml @@ -0,0 +1,20 @@ + + + + Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported. + Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions. + One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. + + diff --git a/xmldoc/formats/mxf.xml b/xmldoc/formats/mxf.xml new file mode 100644 index 000000000..c5b511c46 --- /dev/null +++ b/xmldoc/formats/mxf.xml @@ -0,0 +1,8 @@ + + + + Maptech Exchange Format - Another CSV format file. This +format complies with (at least) Maptech Terrain Navigator, Terrain +Professional, Take a Hike, and ExpertGPS import/export MFX. +Contributed by Alex Mottram. + diff --git a/xmldoc/formats/navicache.xml b/xmldoc/formats/navicache.xml new file mode 100644 index 000000000..6400ce3c4 --- /dev/null +++ b/xmldoc/formats/navicache.xml @@ -0,0 +1,9 @@ + + + + This is the XML format that's used by Navicache.com for +their geocaching data. There are a number of fields in it that are +marked "required" but are Navicache-specific, so GPSBabel can not +write these files, but we can still read them. navicache.com + + diff --git a/xmldoc/formats/netstumbler.xml b/xmldoc/formats/netstumbler.xml new file mode 100644 index 000000000..4bdbfc777 --- /dev/null +++ b/xmldoc/formats/netstumbler.xml @@ -0,0 +1,21 @@ + +This format reads summary files from NetStumbler +0.4 or MacStumbler. + + +The default behavior when creating waypoints is to use the SSID for +the short name, and information about the access point for the +description. When the SSID is not unique, is not available, or +consists of whitespace, a short name is synthesized. + + +Different icons are assigned to encrypted, +non-encrypted, stealth, and non-stealth access points; these may be +changed with options. + + +NetStumbler + + +MacStumbler + diff --git a/xmldoc/formats/nima.xml b/xmldoc/formats/nima.xml new file mode 100644 index 000000000..ea2790de4 --- /dev/null +++ b/xmldoc/formats/nima.xml @@ -0,0 +1,6 @@ + + + + This is a CSV format from the National Imagery and Mapping +Agency. + diff --git a/xmldoc/formats/nmea.xml b/xmldoc/formats/nmea.xml new file mode 100644 index 000000000..955f55e4c --- /dev/null +++ b/xmldoc/formats/nmea.xml @@ -0,0 +1,36 @@ + + + This format is the file representation of the NMEA +(National Marine Electronics Association) 0183 +log and waypoint format for GPS devices. Some hardware and software +that work with NMEA-0183 formatted data include: + + + + GPS Data Logger + + + GPS TrackMaker + + + GPSMaster + + + NMEAlog + + + VisualGPS + + + GPS Utility + + + GeoConv + + + CommLinx GPS recorder + + + SparkFun GPS Datalogger + + diff --git a/xmldoc/formats/nmn4.xml b/xmldoc/formats/nmn4.xml new file mode 100644 index 000000000..8442ccbd0 --- /dev/null +++ b/xmldoc/formats/nmn4.xml @@ -0,0 +1,10 @@ + + + + Support for Navigon Mobile Navigator route (.rte) files. +This is a very simple text format that only requires coordinates, but +has fields for many other things. We only write coordinates as fields +like 'city' and 'street' cannot typically be populated from other +formats. www.navigon.com + + diff --git a/xmldoc/formats/openoffice.xml b/xmldoc/formats/openoffice.xml new file mode 100644 index 000000000..03f35131a --- /dev/null +++ b/xmldoc/formats/openoffice.xml @@ -0,0 +1,11 @@ + + + + Tab seperated export-all (except geocaching data) file +format. Intended to serve as source for number-processing +applications like OpenOffice, Ploticus and others. Tab was chosen as +delimiter because it is a) supported by both OpenOffice and Ploticus +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich. + diff --git a/xmldoc/formats/options/an1-color.xml b/xmldoc/formats/options/an1-color.xml new file mode 100644 index 000000000..eb6e9d691 --- /dev/null +++ b/xmldoc/formats/options/an1-color.xml @@ -0,0 +1,4 @@ + This option allows you to specify the color for +line or mapnote data. It accepts color names of the form "#FF0000" (red) or any +of the color names from the Cascading Style Sheets (CSS) +specification. diff --git a/xmldoc/formats/options/an1-deficon.xml b/xmldoc/formats/options/an1-deficon.xml new file mode 100644 index 000000000..04238310d --- /dev/null +++ b/xmldoc/formats/options/an1-deficon.xml @@ -0,0 +1,7 @@ + +This option allows you to specify which symbol to use for points that +don't have a symbol already. It defaults to "Red Flag" but it accepts +any symbol name you can put in a DeLorme export file. To find the name +of a specific symbol in Street Atlas, let the mouse pointer hover over +it for a few seconds and the name will be displayed. + diff --git a/xmldoc/formats/options/an1-nogc.xml b/xmldoc/formats/options/an1-nogc.xml new file mode 100644 index 000000000..bdeb9dc1b --- /dev/null +++ b/xmldoc/formats/options/an1-nogc.xml @@ -0,0 +1,8 @@ + +If your original data contains geocaching-specific information such as +difficulty and terrain, GPSBabel will automatically include that information +in the waypoint descriptions in the generated drawing file. If you do not +want that, specify the "nogc" option on the command line: + +gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1 + diff --git a/xmldoc/formats/options/an1-radius.xml b/xmldoc/formats/options/an1-radius.xml new file mode 100644 index 000000000..f919776fd --- /dev/null +++ b/xmldoc/formats/options/an1-radius.xml @@ -0,0 +1,5 @@ + +If the waypoint type is "circle", the "radius" option specifies +the radius of the circles. By default, this is in miles, but it may be +specified in kilometers by adding a 'k'. The default radius is 1/10 mile. + diff --git a/xmldoc/formats/options/an1-road.xml b/xmldoc/formats/options/an1-road.xml new file mode 100644 index 000000000..f71a23181 --- /dev/null +++ b/xmldoc/formats/options/an1-road.xml @@ -0,0 +1,79 @@ + +If you are creating a road layer, you may use the "road" option, which +allows you to change the types of roads based on their names. You can +change multiple roads at the same time. Currently supported types are + + + + +Type +Meaning + + limited + Limited-access freeways + + + toll + Limited-access toll highways + + + ramp + Access ramps for limited-access highways + + + us + National highways (e.g. US routes) + + + primary + Primary State/Provincial routes + + + state + State/Provincial routes + + + major + Major Connectors + + + ferry + Ferry Routes + + + local + Local Roads + + + editable + User-drawn Roads + + + + +GPSBabel defaults to creating editable roads. These are routed just like +local roads, but may be edited with the drawing tools in Street Atlas. + + + +This option has a special format that is best demonstrated by example: + + +"road=I-599!limited!Beecher St.!major" + + +This option will cause any road named "I-599" to become a limited-access +highway and any road named "Beecher St." to become a major connector. Note +that roads that have had their types changed in this way are not editable +in Street Atlas, so make sure they are where you want them before you +change them, and make sure to keep a backup of your original road layer. +Note that the ! is a shell metacharacter in bash and possibly other shells, +so you may have to use single quotes or some other escape mechanism. + + + +There is a tutorial on +how +to create an onramp for a limited access highway in Street Atlas USA +using GPSBabel. + diff --git a/xmldoc/formats/options/an1-type.xml b/xmldoc/formats/options/an1-type.xml new file mode 100644 index 000000000..aa21357ff --- /dev/null +++ b/xmldoc/formats/options/an1-type.xml @@ -0,0 +1,7 @@ + This option specifies the type of the drawing layer +to be created. The supported values are "drawing", "road", "trail", +"waypoint", or "track". If you do not specify a type, the default +will be either the type of the previous an1 file or "drawing" if there +is no previous file. This lets you merge, for example, two road layers +without having to specify "type=road" for the output. + diff --git a/xmldoc/formats/options/an1-wpt_type.xml b/xmldoc/formats/options/an1-wpt_type.xml new file mode 100644 index 000000000..dbea684a2 --- /dev/null +++ b/xmldoc/formats/options/an1-wpt_type.xml @@ -0,0 +1,13 @@ + +This option specifies how to represent point data in the draw file. +Valid waypoint types are "symbol", "text", "mapnote", "circle", and "image". +The default is "symbol". + + +If you specify a waypoint type of "image", you should make sure that the +icon descriptions of your waypoints are the full names, including drive letters +and full path, of image files in a format that works with your DeLorme +product. Note that this means that the .an1 file you generate will not work +on any computer that does not have those images in the same place; this is +part of the design of the an1 format and cannot be avoided. + diff --git a/xmldoc/formats/options/an1-zoom.xml b/xmldoc/formats/options/an1-zoom.xml new file mode 100644 index 000000000..ddfe572b3 --- /dev/null +++ b/xmldoc/formats/options/an1-zoom.xml @@ -0,0 +1,7 @@ + +This option specifies at what zoom level Street Atlas will begin showing +reduced versions of your symbols. The default is 10. Setting zoom to 0 will +disable this feature. Setting it to anything but the default will override +the zoom level specified on any waypoints that were read from an existing +an1 file; this is by design. + diff --git a/xmldoc/formats/options/bcr-index.xml b/xmldoc/formats/options/bcr-index.xml new file mode 100644 index 000000000..2d981b38b --- /dev/null +++ b/xmldoc/formats/options/bcr-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o bcr,index=1 -F route1.bcr -o bcr,index=2 -F route2.bcr + diff --git a/xmldoc/formats/options/bcr-name.xml b/xmldoc/formats/options/bcr-name.xml new file mode 100644 index 000000000..575866e3a --- /dev/null +++ b/xmldoc/formats/options/bcr-name.xml @@ -0,0 +1,5 @@ + +This route specifies the name of the route. This is particularly useful if +the route came from an input format that did not support named routes, but +it may also be used to rename a route. + diff --git a/xmldoc/formats/options/bcr-radius.xml b/xmldoc/formats/options/bcr-radius.xml new file mode 100644 index 000000000..f41a98fa5 --- /dev/null +++ b/xmldoc/formats/options/bcr-radius.xml @@ -0,0 +1,9 @@ + +This option instructs GPSBabel to use a different value for the radius of +the earth when converting between the Mercator projection and geographic +coordinates. The default value is 6371000.0 meters. + + +Careful experimentation with this value may help to reduce conversion +errors. + diff --git a/xmldoc/formats/options/cetus-appendicon.xml b/xmldoc/formats/options/cetus-appendicon.xml new file mode 100644 index 000000000..9a52e4eef --- /dev/null +++ b/xmldoc/formats/options/cetus-appendicon.xml @@ -0,0 +1,7 @@ + +This option will add the icon description to the end of the waypoint +description on output. This can be useful if the icon is used to convey +important information about the waypoint. For example, the icon might be +"found geocache" or "unfound geocache"; it might be useful to know that when +looking at a list of icons in Cetus. + diff --git a/xmldoc/formats/options/cetus-dbname.xml b/xmldoc/formats/options/cetus-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/cetus-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/compegps-deficon.xml b/xmldoc/formats/options/compegps-deficon.xml new file mode 100644 index 000000000..959502d59 --- /dev/null +++ b/xmldoc/formats/options/compegps-deficon.xml @@ -0,0 +1,3 @@ + +This option specifies the default icon name on output. + diff --git a/xmldoc/formats/options/compegps-index.xml b/xmldoc/formats/options/compegps-index.xml new file mode 100644 index 000000000..dfccba67e --- /dev/null +++ b/xmldoc/formats/options/compegps-index.xml @@ -0,0 +1,8 @@ + +Because this format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o compegps,index=1 -F route1.txt -o compegps,index=2 -F route2.txt diff --git a/xmldoc/formats/options/compegps-radius.xml b/xmldoc/formats/options/compegps-radius.xml new file mode 100644 index 000000000..de60e1a79 --- /dev/null +++ b/xmldoc/formats/options/compegps-radius.xml @@ -0,0 +1,3 @@ + +This option specifies the default proximity for waypoints and route points. + diff --git a/xmldoc/formats/options/compegps-snlen.xml b/xmldoc/formats/options/compegps-snlen.xml new file mode 100644 index 000000000..54248cfda --- /dev/null +++ b/xmldoc/formats/options/compegps-snlen.xml @@ -0,0 +1,4 @@ + +This option specifies the default length for short names generated on output. +The default length is 16. + diff --git a/xmldoc/formats/options/coto-zerocat.xml b/xmldoc/formats/options/coto-zerocat.xml new file mode 100644 index 000000000..a8230f5f0 --- /dev/null +++ b/xmldoc/formats/options/coto-zerocat.xml @@ -0,0 +1,4 @@ + +This option specifies a name for the "Not Assigned" category in the Palm +database. The default is "Not Assigned". + diff --git a/xmldoc/formats/options/dmtlog-index.xml b/xmldoc/formats/options/dmtlog-index.xml new file mode 100644 index 000000000..69cfb72c7 --- /dev/null +++ b/xmldoc/formats/options/dmtlog-index.xml @@ -0,0 +1,16 @@ + + Convert track number 'index' from source into dmtlog format. + + + The known variants of Tracklog 'digital mapping' files supports only + one track per file. If you have more than one track in source + (f.e MapSource and many others can do such heavy things), you + can specify which track should by used for the conversion. + + + The default index is 1 (the first track of a possible list of tracks). + + + An example usage you can find at the ignrando format, + which uses option index in same manner. + diff --git a/xmldoc/formats/options/garmin-category.xml b/xmldoc/formats/options/garmin-category.xml new file mode 100644 index 000000000..83ed08f2c --- /dev/null +++ b/xmldoc/formats/options/garmin-category.xml @@ -0,0 +1,3 @@ +This numeric option will force waypoints to be written with that +category number when sending to a Garmin receiver that has category +support. It is ignored on receivers without that capability. diff --git a/xmldoc/formats/options/garmin-deficon.xml b/xmldoc/formats/options/garmin-deficon.xml new file mode 100644 index 000000000..26ff03d89 --- /dev/null +++ b/xmldoc/formats/options/garmin-deficon.xml @@ -0,0 +1,17 @@ + +This option specifies the icon or waypoint type to write for each waypoint on +output. + + +If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. + + +Value specified may be a number from the Garmin Protocol Spec or a name +as described in the . + + +This option has no effect on input. + + diff --git a/xmldoc/formats/options/garmin-get_posn.xml b/xmldoc/formats/options/garmin-get_posn.xml new file mode 100644 index 000000000..a7720047c --- /dev/null +++ b/xmldoc/formats/options/garmin-get_posn.xml @@ -0,0 +1,5 @@ +This options gets the current longtitude and latitude from the attached GPS device +and returns it as a single waypoint for further processing. For example, +to return the current position from a USB Garmin to a KML file: +gpsbabel -i garmin,get_posn -f usb: -o kml -F myposition.kml + diff --git a/xmldoc/formats/options/garmin-power_off.xml b/xmldoc/formats/options/garmin-power_off.xml new file mode 100644 index 000000000..63c22850d --- /dev/null +++ b/xmldoc/formats/options/garmin-power_off.xml @@ -0,0 +1,8 @@ +This command forces an immediate powerdown of the addressed Garmin +receiver. It is ignored on hardware that does not support this command. +Obviously, further processing once you have sent a "power off" command to +a unit that supports it is rather futile, so place this option carefully +in your command. + +gpsbabel -o garmin,power_off -F /dev/ttyS0 + diff --git a/xmldoc/formats/options/garmin-snlen.xml b/xmldoc/formats/options/garmin-snlen.xml new file mode 100644 index 000000000..3aa721c67 --- /dev/null +++ b/xmldoc/formats/options/garmin-snlen.xml @@ -0,0 +1,7 @@ +This option overrides the internal logic to figure out how many +characters an addressed Garmin GPS will support when using the '-s' smartname +option. This should be necessary only if you have a receiver type that +GPSBabel doesn't know about or if you want to "dumb down" one unit to match +another, such as wanting waypoint names in a StreetPilot 2720 (which supports +20 character names) to exactly match those in a 60CS (which supports 10). + diff --git a/xmldoc/formats/options/garmin-snwhite.xml b/xmldoc/formats/options/garmin-snwhite.xml new file mode 100644 index 000000000..8a2f1987a --- /dev/null +++ b/xmldoc/formats/options/garmin-snwhite.xml @@ -0,0 +1,2 @@ +This options controls whether spaces are allowed in generated +smart names when using the '-s' option. diff --git a/xmldoc/formats/options/garmin_txt-date.xml b/xmldoc/formats/options/garmin_txt-date.xml new file mode 100644 index 000000000..2f1a3ee59 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-date.xml @@ -0,0 +1,4 @@ + +This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYYY/MM/DD". + diff --git a/xmldoc/formats/options/garmin_txt-datum.xml b/xmldoc/formats/options/garmin_txt-datum.xml new file mode 100644 index 000000000..ce1cadb23 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-datum.xml @@ -0,0 +1,4 @@ + +This option specifies the datum to be used on output. Valid values for this +option are listed in . + diff --git a/xmldoc/formats/options/garmin_txt-dist.xml b/xmldoc/formats/options/garmin_txt-dist.xml new file mode 100644 index 000000000..f3a48251e --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-dist.xml @@ -0,0 +1,5 @@ + +This option specifies the unit to be used when outputting distance +values. Valid values are M for metric (m/km/kph) or S for statute +(ft/mi/mph). + diff --git a/xmldoc/formats/options/garmin_txt-prec.xml b/xmldoc/formats/options/garmin_txt-prec.xml new file mode 100644 index 000000000..962de067f --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-prec.xml @@ -0,0 +1,5 @@ + +This option specifies the precision to be used when writing coordinate values. +Precision is the number of digits after the decimal point. The default +precision is 3. + diff --git a/xmldoc/formats/options/garmin_txt-temp.xml b/xmldoc/formats/options/garmin_txt-temp.xml new file mode 100644 index 000000000..f1de8e27a --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-temp.xml @@ -0,0 +1,4 @@ + +This option specifies the unit to be used when writing temperature values. +Valid values are C for Celsius or F for Fahrenheit. + diff --git a/xmldoc/formats/options/garmin_txt-time.xml b/xmldoc/formats/options/garmin_txt-time.xml new file mode 100644 index 000000000..145c9a4e3 --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-time.xml @@ -0,0 +1,4 @@ + +This option specifies the input and output format for the time. The format +is written similarly to those in Windows. An example format is "hh:mm:ss xx". + diff --git a/xmldoc/formats/options/garmin_txt-utc.xml b/xmldoc/formats/options/garmin_txt-utc.xml new file mode 100644 index 000000000..4c2964e0e --- /dev/null +++ b/xmldoc/formats/options/garmin_txt-utc.xml @@ -0,0 +1,5 @@ + +This option specifies the local time zone to use when writing times. It +is specified as an offset from Universal Coordinated Time (UTC) in hours. +Valid values are from -23 to +23. + diff --git a/xmldoc/formats/options/gdb-cat.xml b/xmldoc/formats/options/gdb-cat.xml new file mode 100644 index 000000000..6b876e911 --- /dev/null +++ b/xmldoc/formats/options/gdb-cat.xml @@ -0,0 +1,4 @@ + +This option specifies the default category for gdb output. It should be a +number from 1 to 16. + diff --git a/xmldoc/formats/options/gdb-ver.xml b/xmldoc/formats/options/gdb-ver.xml new file mode 100644 index 000000000..847a9ac1e --- /dev/null +++ b/xmldoc/formats/options/gdb-ver.xml @@ -0,0 +1,5 @@ + +This option specifies the data format version for the output file. Version +2 is the default. Currently, the only other valid value for this option is +1. + diff --git a/xmldoc/formats/options/gdb-via.xml b/xmldoc/formats/options/gdb-via.xml new file mode 100644 index 000000000..0df42530c --- /dev/null +++ b/xmldoc/formats/options/gdb-via.xml @@ -0,0 +1,5 @@ + +This option instructs GPSBabel to drop hidden (calculated) points from +routes. + + diff --git a/xmldoc/formats/options/geo-deficon.xml b/xmldoc/formats/options/geo-deficon.xml new file mode 100644 index 000000000..96d6f27c9 --- /dev/null +++ b/xmldoc/formats/options/geo-deficon.xml @@ -0,0 +1,17 @@ + +This option specifies the icon or waypoint type to write for each waypoint on +output. + + +If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. + + +There is no list of valid values for this option. + + +This option has no effect on input. + + + diff --git a/xmldoc/formats/options/geo-nuke_placer.xml b/xmldoc/formats/options/geo-nuke_placer.xml new file mode 100644 index 000000000..50d5a92da --- /dev/null +++ b/xmldoc/formats/options/geo-nuke_placer.xml @@ -0,0 +1,9 @@ + +If this option is specified, GPSBabel will not read geocache placer information +from a .loc file on input. That is, it will ignore any placeer names in the +input file. + + +This option has no effect on output. + + diff --git a/xmldoc/formats/options/geoniche-category.xml b/xmldoc/formats/options/geoniche-category.xml new file mode 100644 index 000000000..7060b96b0 --- /dev/null +++ b/xmldoc/formats/options/geoniche-category.xml @@ -0,0 +1,6 @@ + +This option specifies the name of the category in which to place the +waypoints. If this option is not specified, the default category is +"Cache". + + diff --git a/xmldoc/formats/options/geoniche-dbname.xml b/xmldoc/formats/options/geoniche-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/geoniche-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/gpilots-dbname.xml b/xmldoc/formats/options/gpilots-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/gpilots-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/gpspilot-dbname.xml b/xmldoc/formats/options/gpspilot-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/gpspilot-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/gpssim-split.xml b/xmldoc/formats/options/gpssim-split.xml new file mode 100644 index 000000000..51dad87f7 --- /dev/null +++ b/xmldoc/formats/options/gpssim-split.xml @@ -0,0 +1,17 @@ +When this option is specified, GPSBabel will split + split the output into multiple files using the output filename + as a base. For example, if you specify an output file of 'mytrip', + + mytrip-waypoints.gpssim - will contain the waypoints. + mytrip-track0000.gpssim - will contain the first track. + mytrip-track0001.gpssim - will contain the second track. + ... and so on. + mytrip-route0000.gpssim - will contain the first route. + mytrip-route0001.gpssim - will contain the seconds route. + ... and so on. + + + + +Valid values for this option are 0 (off) and 1 (on). The default is '0'. + diff --git a/xmldoc/formats/options/gpssim-wayptspd.xml b/xmldoc/formats/options/gpssim-wayptspd.xml new file mode 100644 index 000000000..ca23812dc --- /dev/null +++ b/xmldoc/formats/options/gpssim-wayptspd.xml @@ -0,0 +1,3 @@ + + This option specifies the speed of the simulation in knots. + diff --git a/xmldoc/formats/options/gpx-gpxver.xml b/xmldoc/formats/options/gpx-gpxver.xml new file mode 100644 index 000000000..8e2ccc3ad --- /dev/null +++ b/xmldoc/formats/options/gpx-gpxver.xml @@ -0,0 +1,11 @@ + +This option specifies the version of the GPX specification to use for +output. The default version is 1.0. The only other valid value for this +option is 1.1. + + +Notice that this is not a full scale XML schema conversion. In particular, +if you have a GPX 1.0 file that has extended namespaces in it (such as a +pocket query from Geocaching.com) just writing it with this option will +result in a horribly mangled GPX file as we can't convert the schema data. + diff --git a/xmldoc/formats/options/gpx-logpoint.xml b/xmldoc/formats/options/gpx-logpoint.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/gpx-logpoint.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/gpx-snlen.xml b/xmldoc/formats/options/gpx-snlen.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/gpx-snlen.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/gpx-suppresswhite.xml b/xmldoc/formats/options/gpx-suppresswhite.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/gpx-suppresswhite.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/gpx-urlbase.xml b/xmldoc/formats/options/gpx-urlbase.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/gpx-urlbase.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/html-altunits.xml b/xmldoc/formats/options/html-altunits.xml new file mode 100644 index 000000000..586dee672 --- /dev/null +++ b/xmldoc/formats/options/html-altunits.xml @@ -0,0 +1,4 @@ + +This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. + diff --git a/xmldoc/formats/options/html-degformat.xml b/xmldoc/formats/options/html-degformat.xml new file mode 100644 index 000000000..25d45942b --- /dev/null +++ b/xmldoc/formats/options/html-degformat.xml @@ -0,0 +1,5 @@ + +When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. + diff --git a/xmldoc/formats/options/html-encrypt.xml b/xmldoc/formats/options/html-encrypt.xml new file mode 100644 index 000000000..2d7d96091 --- /dev/null +++ b/xmldoc/formats/options/html-encrypt.xml @@ -0,0 +1,3 @@ + +Use this option to encrypt hints from Groundspeak GPX files. + diff --git a/xmldoc/formats/options/html-logs.xml b/xmldoc/formats/options/html-logs.xml new file mode 100644 index 000000000..9e25a13ea --- /dev/null +++ b/xmldoc/formats/options/html-logs.xml @@ -0,0 +1,3 @@ + +Use this option to include Groundspeak cache logs in the created document. + diff --git a/xmldoc/formats/options/html-stylesheet.xml b/xmldoc/formats/options/html-stylesheet.xml new file mode 100644 index 000000000..82f38d356 --- /dev/null +++ b/xmldoc/formats/options/html-stylesheet.xml @@ -0,0 +1,4 @@ + +Use this option to specify a CSS style sheet to be used with the +resulting HTML file. + diff --git a/xmldoc/formats/options/igc-timeadj.xml b/xmldoc/formats/options/igc-timeadj.xml new file mode 100644 index 000000000..2d6def3c8 --- /dev/null +++ b/xmldoc/formats/options/igc-timeadj.xml @@ -0,0 +1,16 @@ + +Sometimes there is a discrepancy between the internal clock in the barograph +instrument and GPS time which can result in the altitude and ground positions +not correlating correctly. This can be corrected manually by passing the time +difference in seconds between the two time domains through the "timeadj" +parameter. This can be any positive or negative integer: + +gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=27 -F my3D.igc + +GPSBabel can also attempt to deduce the time difference automatically. This +is done by comparing the time that it thinks that you landed on the GPS track +and the barograph and adjusting accordingly: + +gpsbabel -i gpx -f baro.gpx -i igc -f my2D.igc -o igc,timeadj=auto -F my3D.igc + + diff --git a/xmldoc/formats/options/ignrando-index.xml b/xmldoc/formats/options/ignrando-index.xml new file mode 100644 index 000000000..42c8f4e6f --- /dev/null +++ b/xmldoc/formats/options/ignrando-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one track, this option may be used +on output to select a single track from a collection of +tracks read from a more expressive format. If you have, say, a +gpx file that contains two tracks, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f tracks.gpx -o ignrando,index=1 -F track1.txt -o ignrando,index=2 -F track2.txt + diff --git a/xmldoc/formats/options/kml-deficon.xml b/xmldoc/formats/options/kml-deficon.xml new file mode 100644 index 000000000..5f94e2595 --- /dev/null +++ b/xmldoc/formats/options/kml-deficon.xml @@ -0,0 +1,3 @@ + +This option specifies the default name for waypoint icons + diff --git a/xmldoc/formats/options/kml-extrude.xml b/xmldoc/formats/options/kml-extrude.xml new file mode 100644 index 000000000..2cb3a4027 --- /dev/null +++ b/xmldoc/formats/options/kml-extrude.xml @@ -0,0 +1,7 @@ + +This option is a boolean flag to specicy whether Google Earth should +draw lines from trackpoints to the ground. It defaults to '0', which +means no extrusion lines are drawn. The option of '1' is, of course, +most useful for points that aren't actually on the ground such as those +be captured from planes. + diff --git a/xmldoc/formats/options/kml-floating.xml b/xmldoc/formats/options/kml-floating.xml new file mode 100644 index 000000000..6a26606d0 --- /dev/null +++ b/xmldoc/formats/options/kml-floating.xml @@ -0,0 +1,9 @@ + +When this option is nonzero, altitudes are allowed to float above or below +the ground surface. By default, this option is zero so that altitudes are +clamped to the ground. Specify to allow them to +float. + + +This option is more useful to pilots than to hikers. + diff --git a/xmldoc/formats/options/kml-labels.xml b/xmldoc/formats/options/kml-labels.xml new file mode 100644 index 000000000..1caf013b7 --- /dev/null +++ b/xmldoc/formats/options/kml-labels.xml @@ -0,0 +1,4 @@ + +When this option is zero, no labels are added for track and route points. +This option defaults to one, so labels are added by default. + diff --git a/xmldoc/formats/options/kml-line_color.xml b/xmldoc/formats/options/kml-line_color.xml new file mode 100644 index 000000000..33892c4c7 --- /dev/null +++ b/xmldoc/formats/options/kml-line_color.xml @@ -0,0 +1,5 @@ + +This option specifies the line color as a hexadecimal number in +AABBGGRR format, where A is alpha, B is blue, G is green, and R is red. + + diff --git a/xmldoc/formats/options/kml-line_width.xml b/xmldoc/formats/options/kml-line_width.xml new file mode 100644 index 000000000..0dfb9b040 --- /dev/null +++ b/xmldoc/formats/options/kml-line_width.xml @@ -0,0 +1,4 @@ + +This option specifies the width of the drawn lines in pixels. The default +value is six pixels. + diff --git a/xmldoc/formats/options/kml-lines.xml b/xmldoc/formats/options/kml-lines.xml new file mode 100644 index 000000000..fbe2dafaa --- /dev/null +++ b/xmldoc/formats/options/kml-lines.xml @@ -0,0 +1,6 @@ + +When this option is nonzero, GPSBabel draws lines between points in +tracks and routes. The default value for this option is 1, which causes +lines to be drawn by default. To disable line-drawing, specify +. + diff --git a/xmldoc/formats/options/kml-max_position_points.xml b/xmldoc/formats/options/kml-max_position_points.xml new file mode 100644 index 000000000..6698c2dd2 --- /dev/null +++ b/xmldoc/formats/options/kml-max_position_points.xml @@ -0,0 +1,4 @@ + + This option allows you to specify the number of points kept + in the 'snail trail' generated in the realtime tracking mode. + diff --git a/xmldoc/formats/options/kml-points.xml b/xmldoc/formats/options/kml-points.xml new file mode 100644 index 000000000..3f8241d46 --- /dev/null +++ b/xmldoc/formats/options/kml-points.xml @@ -0,0 +1,6 @@ + +When this option is nonzero, GPSBabel draws placemarks for tracks and routes. +The default value for this option is 1, which causes placemarks to be drawn. +To disable drawing of placemarks, specify . + + diff --git a/xmldoc/formats/options/kml-trackdata.xml b/xmldoc/formats/options/kml-trackdata.xml new file mode 100644 index 000000000..a27154033 --- /dev/null +++ b/xmldoc/formats/options/kml-trackdata.xml @@ -0,0 +1,8 @@ + +This is a boolean flag that controls +whether GPSBabel writes extensive data for each trackpoint generated. +By default computed speed, timestamps, and so on are written with the default +of '1' for this option. If you are writing large tracks and do not value +this information, you can reduce the size of the generated file substantially +by turning this flag off by setting it to '0'. + diff --git a/xmldoc/formats/options/kml-units.xml b/xmldoc/formats/options/kml-units.xml new file mode 100644 index 000000000..7d2db21f5 --- /dev/null +++ b/xmldoc/formats/options/kml-units.xml @@ -0,0 +1,5 @@ + +Units is a simple option. Specify 's' for "statute" (miles, feet, and +other things that don't sensibly convert to each other, but are craved +by Americans) or 'm' for "metric". + diff --git a/xmldoc/formats/options/lowranceusr-break.xml b/xmldoc/formats/options/lowranceusr-break.xml new file mode 100644 index 000000000..fc1503704 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-break.xml @@ -0,0 +1,4 @@ + +This option breaks track segments into separate tracks when reading a .USR +file. + diff --git a/xmldoc/formats/options/lowranceusr-ignoreicons.xml b/xmldoc/formats/options/lowranceusr-ignoreicons.xml new file mode 100644 index 000000000..7930731c0 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-ignoreicons.xml @@ -0,0 +1,3 @@ + +This option instructs GPSBabel to not convert icons to waypoints on input. + diff --git a/xmldoc/formats/options/lowranceusr-merge.xml b/xmldoc/formats/options/lowranceusr-merge.xml new file mode 100644 index 000000000..f5c8721b3 --- /dev/null +++ b/xmldoc/formats/options/lowranceusr-merge.xml @@ -0,0 +1,3 @@ + +This option merges all tracks into a single track with multiple segments. + diff --git a/xmldoc/formats/options/magellan-deficon.xml b/xmldoc/formats/options/magellan-deficon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/magellan-deficon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/magellan-maxcmts.xml b/xmldoc/formats/options/magellan-maxcmts.xml new file mode 100644 index 000000000..1c46dd108 --- /dev/null +++ b/xmldoc/formats/options/magellan-maxcmts.xml @@ -0,0 +1,13 @@ + +The maxcmts option allows you to specify the number comments that will +be sent to the unit. + + +Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. + diff --git a/xmldoc/formats/options/magellan1-baud.xml b/xmldoc/formats/options/magellan1-baud.xml new file mode 100644 index 000000000..0682faa0a --- /dev/null +++ b/xmldoc/formats/options/magellan1-baud.xml @@ -0,0 +1,8 @@ + + This option causes GPSBabel to use the given baud rate for serial + communications. It must match the given baud rate on the receiver. The + default value matches the default on the receiver, 4800. + + + Valid options are 1200, 2400, 4800, 9600, 19200, 57600, and 115200. + diff --git a/xmldoc/formats/options/magellan1-deficon.xml b/xmldoc/formats/options/magellan1-deficon.xml new file mode 100644 index 000000000..f1d272b05 --- /dev/null +++ b/xmldoc/formats/options/magellan1-deficon.xml @@ -0,0 +1,15 @@ + +This option specifies the icon or waypoint type to write for each waypoint on +output. + + +If this option is specified, its value will be used for all waypoints, not +just those that do not already have descriptions. That is, this option +overrides any icon description that might be in the input file. + + + +This option has no effect on input. + diff --git a/xmldoc/formats/options/magellan1-maxcmts.xml b/xmldoc/formats/options/magellan1-maxcmts.xml new file mode 100644 index 000000000..1c46dd108 --- /dev/null +++ b/xmldoc/formats/options/magellan1-maxcmts.xml @@ -0,0 +1,13 @@ + +The maxcmts option allows you to specify the number comments that will +be sent to the unit. + + +Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. + diff --git a/xmldoc/formats/options/magellan1-noack.xml b/xmldoc/formats/options/magellan1-noack.xml new file mode 100644 index 000000000..f8d84cab2 --- /dev/null +++ b/xmldoc/formats/options/magellan1-noack.xml @@ -0,0 +1,17 @@ + +Magellan's protocol specification strongly encourages the use of software +acknowledgements on every packets. This is a simple "this is what I think +I heard. If you agree that I heard it correctly, let's go to the next packet" +handshake that is used to ensure the integrity of the data transfer. + + +Certain firmware versions have problems handling this which makes transfers +unnecessarily slow. Transfers on all units at high serial speeds are also +severely restricted by this process. + + +In controlled environments (good cables, low electrical noise, receiving +from the unit, not doing donuts with the unit set to "track up" at a 150 +mile scale with 500 waypoints on the screen) it is sometimes useful to +release that safety belt by using the "noack" suboption. + diff --git a/xmldoc/formats/options/magellan1-nukewpt.xml b/xmldoc/formats/options/magellan1-nukewpt.xml new file mode 100644 index 000000000..5ca891611 --- /dev/null +++ b/xmldoc/formats/options/magellan1-nukewpt.xml @@ -0,0 +1,10 @@ + +This option erases all waypoints in the receiver before doing a transfer. + + +This is a convenient option to use in automated processes where you want +to ensure the units starts with a clean state before sending waypoints to +it. Using this option on transmit is a better idea than doing it on +receive since the latter would erase all the waypoints before asking the +unit to send all the waypoints. + diff --git a/xmldoc/formats/options/magellanx-deficon.xml b/xmldoc/formats/options/magellanx-deficon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/magellanx-deficon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/magellanx-maxcmts.xml b/xmldoc/formats/options/magellanx-maxcmts.xml new file mode 100644 index 000000000..1c46dd108 --- /dev/null +++ b/xmldoc/formats/options/magellanx-maxcmts.xml @@ -0,0 +1,13 @@ + +The maxcmts option allows you to specify the number comments that will +be sent to the unit. + + +Magellan receivers allow a maximum of 200 waypoint comments. Unfortunately, +DirectRoute uses waypoint comments to provide next turn directions for +navigation pop-ups and that comes from that pool of 200 comments. It +is therefore sometimes convenient to limit the number of waypoint +comments written to the receiver. For example, a geocacher might want +to upload 400 waypoints, but only 190 with comments so that DirectRoute +could provide driving directions for the next ten turns. + diff --git a/xmldoc/formats/options/mapsend-trkver.xml b/xmldoc/formats/options/mapsend-trkver.xml new file mode 100644 index 000000000..5e5421081 --- /dev/null +++ b/xmldoc/formats/options/mapsend-trkver.xml @@ -0,0 +1,6 @@ + +This option sets the MapSend version to generate TRK files, +since new MapSend versions can't open version 3 files. +Valid values are 3 (MapSend v3.0) or 4 (MapSend v4.0 and v4.1). + + diff --git a/xmldoc/formats/options/mapsource-mpsmergeout.xml b/xmldoc/formats/options/mapsource-mpsmergeout.xml new file mode 100644 index 000000000..8b06e42d2 --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsmergeout.xml @@ -0,0 +1,5 @@ + +This option causes the output to be merged with a pre-existing output file. +This allows MapSource sections that aren't handled by GPSBabel (e.g. map sets) +to be preserved. + diff --git a/xmldoc/formats/options/mapsource-mpsusedepth.xml b/xmldoc/formats/options/mapsource-mpsusedepth.xml new file mode 100644 index 000000000..08b6dfd34 --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsusedepth.xml @@ -0,0 +1,5 @@ + +This option causes GPSBabel to write depth values for waypoints. Most +input formats do not support depth values, so the default is to not write +them. + diff --git a/xmldoc/formats/options/mapsource-mpsuseprox.xml b/xmldoc/formats/options/mapsource-mpsuseprox.xml new file mode 100644 index 000000000..c09a64b5f --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsuseprox.xml @@ -0,0 +1,5 @@ + +This option causes GPSBabel to write proximity values for waypoints. Most +input formats do not support proximity values, so the default is to not write +them. + diff --git a/xmldoc/formats/options/mapsource-mpsverout.xml b/xmldoc/formats/options/mapsource-mpsverout.xml new file mode 100644 index 000000000..6aa3d7bbd --- /dev/null +++ b/xmldoc/formats/options/mapsource-mpsverout.xml @@ -0,0 +1,5 @@ + +This option specifies the format version for the output file. The default +is version 5, as noted above. Supported versions are 3, 4, and 5. + + diff --git a/xmldoc/formats/options/mapsource-snlen.xml b/xmldoc/formats/options/mapsource-snlen.xml new file mode 100644 index 000000000..40e494453 --- /dev/null +++ b/xmldoc/formats/options/mapsource-snlen.xml @@ -0,0 +1,4 @@ + +This option specifies the length of generated short names on output. The +default is 10 characters. + diff --git a/xmldoc/formats/options/mapsource-snwhite.xml b/xmldoc/formats/options/mapsource-snwhite.xml new file mode 100644 index 000000000..0655b1894 --- /dev/null +++ b/xmldoc/formats/options/mapsource-snwhite.xml @@ -0,0 +1,4 @@ + +This option specifies whether to allow whitespace (space, tab, etc.) in +generated short names on output. The default is to not allow whitespace. + diff --git a/xmldoc/formats/options/navicache-noretired.xml b/xmldoc/formats/options/navicache-noretired.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/navicache-noretired.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/netstumbler-nseicon.xml b/xmldoc/formats/options/netstumbler-nseicon.xml new file mode 100644 index 000000000..4a6d622e8 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-nseicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +non-stealth, encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-nsneicon.xml b/xmldoc/formats/options/netstumbler-nsneicon.xml new file mode 100644 index 000000000..bf0f7cc35 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-nsneicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +non-stealth, non-encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-seicon.xml b/xmldoc/formats/options/netstumbler-seicon.xml new file mode 100644 index 000000000..3f0accbdc --- /dev/null +++ b/xmldoc/formats/options/netstumbler-seicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +stealth, encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-sneicon.xml b/xmldoc/formats/options/netstumbler-sneicon.xml new file mode 100644 index 000000000..174ad2b32 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-sneicon.xml @@ -0,0 +1,4 @@ + +This option specifies the name of the icon to use for +stealth, non-encrypted access points. + diff --git a/xmldoc/formats/options/netstumbler-snmac.xml b/xmldoc/formats/options/netstumbler-snmac.xml new file mode 100644 index 000000000..db2a39481 --- /dev/null +++ b/xmldoc/formats/options/netstumbler-snmac.xml @@ -0,0 +1,4 @@ + +This option causes GPSBabel to use the MAC address as the short name for the +waypoint. The unmodified SSID is included in the waypoint description. + diff --git a/xmldoc/formats/options/nmea-baud.xml b/xmldoc/formats/options/nmea-baud.xml new file mode 100644 index 000000000..5aff834a1 --- /dev/null +++ b/xmldoc/formats/options/nmea-baud.xml @@ -0,0 +1,4 @@ + +To the "nmea" module, the "baud" option specifies the baud rate of the +serial connection when used with the real-time tracking option. + diff --git a/xmldoc/formats/options/nmea-date.xml b/xmldoc/formats/options/nmea-date.xml new file mode 100644 index 000000000..81467a8c9 --- /dev/null +++ b/xmldoc/formats/options/nmea-date.xml @@ -0,0 +1,10 @@ + +On input, track points with times but no dates will have this date applied. + + +This is necessary because some NMEA sentences contain times but no dates. If +this option is not specified and the date cannot be determined from one or +more of the available NMEA sentences, the tracks will be discarded. + + + diff --git a/xmldoc/formats/options/nmea-get_posn.xml b/xmldoc/formats/options/nmea-get_posn.xml new file mode 100644 index 000000000..dbc7b2ce6 --- /dev/null +++ b/xmldoc/formats/options/nmea-get_posn.xml @@ -0,0 +1,3 @@ +This options, when specified, returns the current position as a single +waypoint. + diff --git a/xmldoc/formats/options/nmea-gpgga.xml b/xmldoc/formats/options/nmea-gpgga.xml new file mode 100644 index 000000000..2b89b5072 --- /dev/null +++ b/xmldoc/formats/options/nmea-gpgga.xml @@ -0,0 +1,8 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPGGA sentences. The default is to read or write GPGGA sentences. To +disable GPGGA sentences, specify . + + +GPGGA sentences contain the location and quality of the GPS position fix. + diff --git a/xmldoc/formats/options/nmea-gpgsa.xml b/xmldoc/formats/options/nmea-gpgsa.xml new file mode 100644 index 000000000..40412dd84 --- /dev/null +++ b/xmldoc/formats/options/nmea-gpgsa.xml @@ -0,0 +1,12 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPGSA sentences. The default is to read or write GPGSA sentences. To +disable GPGSA sentences, specify . + + +GPGSA sentences contain information on the quality of the positional fix +and the individual satellites from which it was derived. However, GPSBabel +neither reads nor writes the individual satellite data. On input, the +satellite fields are ignored and on output they are left blank. + + diff --git a/xmldoc/formats/options/nmea-gprmc.xml b/xmldoc/formats/options/nmea-gprmc.xml new file mode 100644 index 000000000..d6b3f2d1e --- /dev/null +++ b/xmldoc/formats/options/nmea-gprmc.xml @@ -0,0 +1,11 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPRMC sentences. The default is to read or write GPRMC sentences. To +disable GPRMC sentences, specify . + + +GPRMC sentences contain the "recommended mimimum" positional information, +including date and time, heading, and velocity. Note that they do not +include altitude. For altitude, you will have to include GPGGA sentences. + + diff --git a/xmldoc/formats/options/nmea-gpvtg.xml b/xmldoc/formats/options/nmea-gpvtg.xml new file mode 100644 index 000000000..85d587517 --- /dev/null +++ b/xmldoc/formats/options/nmea-gpvtg.xml @@ -0,0 +1,11 @@ + +This option tells GPSBabel whether to read (on input) or write (on output) +GPVTG sentences. The default is to read or write GPVTG sentences. To +disable GPVTG sentences, specify . + + +GPVTG sentences contain information about the heading and the speed at the +time of the fix. They do not contain any location information; for that +you will need either or both of GPGGA or GPRMC. + + diff --git a/xmldoc/formats/options/nmea-pause.xml b/xmldoc/formats/options/nmea-pause.xml new file mode 100644 index 000000000..72e42ec73 --- /dev/null +++ b/xmldoc/formats/options/nmea-pause.xml @@ -0,0 +1,31 @@ + +This option tells GPSBabel to pause between individual track records when +used on output. This may be used with appropriate external software or +hardware to simulate a GPS receiver for testing purposes. On Unix, for +example, you may use a named pipe to feed the output from GPSBabel to gpsd. + + +If a value for this option is specified, it is in seconds and it may be +either a whole number of seconds or a fraction (e.g. 0.5 for a 1/2 second +pause between trackpoints.) + + +If this option is specified without a value, the time between adjacent +trackpoints will be computed and used for the length of the pause. That is, +if your trackpoints are 5 seconds apart, GPSBabel will pause 5 seconds +between trackpoints. + + +Note that very long tracks may be subject to clock drift, as GPSBabel does +not take into account the amount of time it may take to write the NMEA +sentences. Also, there is no guarantee that it will pause for exactly the +specified number of seconds between samples; different operating systems +will allow greater or lesser precision for timers, so actual precision may +be as much as plus or minus 100 milliseconds. + + +If you are using this option with compressed or simplified tracks from +your handheld GPS receiver, you might find the +interpolate filter useful. + + diff --git a/xmldoc/formats/options/nmea-snlen.xml b/xmldoc/formats/options/nmea-snlen.xml new file mode 100644 index 000000000..36e9c734b --- /dev/null +++ b/xmldoc/formats/options/nmea-snlen.xml @@ -0,0 +1,6 @@ + +This option specifies the maximum length to be used for waypoint names in +the GPWPL sentence. Longer names will be shortened to no more than this +length, but all waypoint names will remain unique. + + diff --git a/xmldoc/formats/options/nmn4-index.xml b/xmldoc/formats/options/nmn4-index.xml new file mode 100644 index 000000000..8b7f0c4f0 --- /dev/null +++ b/xmldoc/formats/options/nmn4-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one route, this option may be used +on output to select a single route from a collection of +routes read from a more expressive format. If you have, say, a +gpx file that contains two routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o nmn4,index=1 -F route1.rte -o nmn4,index=2 -F route2.rte + diff --git a/xmldoc/formats/options/ozi-snlen.xml b/xmldoc/formats/options/ozi-snlen.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/ozi-snlen.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/ozi-snunique.xml b/xmldoc/formats/options/ozi-snunique.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/ozi-snunique.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/ozi-snupper.xml b/xmldoc/formats/options/ozi-snupper.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/ozi-snupper.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/ozi-snwhite.xml b/xmldoc/formats/options/ozi-snwhite.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/ozi-snwhite.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/ozi-wptbgcolor.xml b/xmldoc/formats/options/ozi-wptbgcolor.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/ozi-wptbgcolor.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/ozi-wptfgcolor.xml b/xmldoc/formats/options/ozi-wptfgcolor.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/ozi-wptfgcolor.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/palmdoc-bookmarks_short.xml b/xmldoc/formats/options/palmdoc-bookmarks_short.xml new file mode 100644 index 000000000..b1c22efb5 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-bookmarks_short.xml @@ -0,0 +1,9 @@ + +If you would like the generated bookmarks to start with +the short name for the waypoint, specify this option. + + +This is particularly useful when used in combination with the 'sort' +filter. + + diff --git a/xmldoc/formats/options/palmdoc-dbname.xml b/xmldoc/formats/options/palmdoc-dbname.xml new file mode 100644 index 000000000..626baaa86 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-dbname.xml @@ -0,0 +1,5 @@ + +This option specifies the internal name for the document. This is the name +that appears in your document reader, not the name of the file that is created +on your computer. + diff --git a/xmldoc/formats/options/palmdoc-encrypt.xml b/xmldoc/formats/options/palmdoc-encrypt.xml new file mode 100644 index 000000000..2d7d96091 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-encrypt.xml @@ -0,0 +1,3 @@ + +Use this option to encrypt hints from Groundspeak GPX files. + diff --git a/xmldoc/formats/options/palmdoc-logs.xml b/xmldoc/formats/options/palmdoc-logs.xml new file mode 100644 index 000000000..9e25a13ea --- /dev/null +++ b/xmldoc/formats/options/palmdoc-logs.xml @@ -0,0 +1,3 @@ + +Use this option to include Groundspeak cache logs in the created document. + diff --git a/xmldoc/formats/options/palmdoc-nosep.xml b/xmldoc/formats/options/palmdoc-nosep.xml new file mode 100644 index 000000000..75e79abf7 --- /dev/null +++ b/xmldoc/formats/options/palmdoc-nosep.xml @@ -0,0 +1,3 @@ + +To suppress the dashed lines between waypoints, use this option. + diff --git a/xmldoc/formats/options/pathaway-date.xml b/xmldoc/formats/options/pathaway-date.xml new file mode 100644 index 000000000..e505b5eb7 --- /dev/null +++ b/xmldoc/formats/options/pathaway-date.xml @@ -0,0 +1,4 @@ + +This option specifies the input and output format for the date. The format +is written similarly to those in Windows. An example format is "YYMMDD". + diff --git a/xmldoc/formats/options/pathaway-dbname.xml b/xmldoc/formats/options/pathaway-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/pathaway-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/pathaway-deficon.xml b/xmldoc/formats/options/pathaway-deficon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/pathaway-deficon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/pathaway-snlen.xml b/xmldoc/formats/options/pathaway-snlen.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/pathaway-snlen.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/pcx-cartoexploreur.xml b/xmldoc/formats/options/pcx-cartoexploreur.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/pcx-cartoexploreur.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/pcx-deficon.xml b/xmldoc/formats/options/pcx-deficon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/pcx-deficon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/quovadis-dbname.xml b/xmldoc/formats/options/quovadis-dbname.xml new file mode 100644 index 000000000..f4b336e5e --- /dev/null +++ b/xmldoc/formats/options/quovadis-dbname.xml @@ -0,0 +1,6 @@ + +This option specifies the database name for the output file. This name is +not the same thing as the file name on your computer; this is the name that +appears in the file browser on your handheld. + + diff --git a/xmldoc/formats/options/saroute-controls.xml b/xmldoc/formats/options/saroute-controls.xml new file mode 100644 index 000000000..e532c0c6d --- /dev/null +++ b/xmldoc/formats/options/saroute-controls.xml @@ -0,0 +1,10 @@ +This option lets you read the control points +(start, end, vias, and stops) for your route as well as the route +itself. The default for this option is 'none', which won't read the +control points. You may also specify 'waypoints', which reads the +control points as waypoints, or 'route', which creates an extra route +named 'control points' containing just the control points in order. +Note that if your goal is to create an arc or other CSV file, you +should use 'none' (or not use this option, which is the same +thing.) + diff --git a/xmldoc/formats/options/saroute-split.xml b/xmldoc/formats/options/saroute-split.xml new file mode 100644 index 000000000..e83fd4d17 --- /dev/null +++ b/xmldoc/formats/options/saroute-split.xml @@ -0,0 +1,5 @@ + This option causes GPSBabel to create separate +routes for each street, creating a new route at each turn point. For +obvious reasons, 'split' cannot be used at the same time as the +'turns_only' or 'turns_important' options. + diff --git a/xmldoc/formats/options/saroute-times.xml b/xmldoc/formats/options/saroute-times.xml new file mode 100644 index 000000000..857b3d3ce --- /dev/null +++ b/xmldoc/formats/options/saroute-times.xml @@ -0,0 +1,5 @@ + This option causes GPSBabel to read the route as if +it were a track, synthesizing times starting from the current time, using +the estimated travel times specified in your route file (you can change your +travel speeds in the DeLorme product you used to create the route file.) + diff --git a/xmldoc/formats/options/saroute-turns_important.xml b/xmldoc/formats/options/saroute-turns_important.xml new file mode 100644 index 000000000..82b793a09 --- /dev/null +++ b/xmldoc/formats/options/saroute-turns_important.xml @@ -0,0 +1,6 @@ + This option only makes sense in +conjunction with the 'simplify' filter. It ensures that the route +simplification process will remove the points corresponding to turns +only after it has removed all other route points. + + diff --git a/xmldoc/formats/options/saroute-turns_only.xml b/xmldoc/formats/options/saroute-turns_only.xml new file mode 100644 index 000000000..1c35dc5d8 --- /dev/null +++ b/xmldoc/formats/options/saroute-turns_only.xml @@ -0,0 +1,4 @@ + This option causes GPSBabel to read only the +waypoints associated with named turns. This should create a list of +waypoints that correspond to the itinerary from Street Atlas. + diff --git a/xmldoc/formats/options/stmsdf-index.xml b/xmldoc/formats/options/stmsdf-index.xml new file mode 100644 index 000000000..301d55b1f --- /dev/null +++ b/xmldoc/formats/options/stmsdf-index.xml @@ -0,0 +1,17 @@ + + Convert route number 'index' from source into sdf format. + + + We have a lot of more expressive formats thats support more than one route. + At this place sdf files are limited to only one single route. With option index + you can specify which route from source should be converted. + + + Our default index is 1. + + + This example will convert route number two and three into separate sdf files: + + gpsbabel -i gdb -f routes.gdb -r -o stmsdf,index=2 -F route-one.sdf -r -o stmsdf,index=3 -F route-three.sdf + + diff --git a/xmldoc/formats/options/stmwpp-index.xml b/xmldoc/formats/options/stmwpp-index.xml new file mode 100644 index 000000000..6187a66a8 --- /dev/null +++ b/xmldoc/formats/options/stmwpp-index.xml @@ -0,0 +1,9 @@ + +Because the format supports only one route or track, this option may be used +on output to select a single route or track from a collection of routes and +tracks read from a more expressive format. If you have, say, a +gpx file that contains three routes, you may +use this option to write them one at a time to individual files. + +gpsbabel -i gpx -f routes.gpx -o stmwpp,index=1 -F route1.txt -o stmwpp,index=2 -F route2.txt -o stmwpp,index=3 -F route3.txt + diff --git a/xmldoc/formats/options/tef-routevia.xml b/xmldoc/formats/options/tef-routevia.xml new file mode 100644 index 000000000..b57880554 --- /dev/null +++ b/xmldoc/formats/options/tef-routevia.xml @@ -0,0 +1,3 @@ + +This option may be used to eliminate calculated route points from the route. + diff --git a/xmldoc/formats/options/text-altunits.xml b/xmldoc/formats/options/text-altunits.xml new file mode 100644 index 000000000..788f88674 --- /dev/null +++ b/xmldoc/formats/options/text-altunits.xml @@ -0,0 +1,4 @@ + +This option should be 'f' if you want the altitude expressed in feet and +'m' for meters. The default is 'f'. + \ No newline at end of file diff --git a/xmldoc/formats/options/text-degformat.xml b/xmldoc/formats/options/text-degformat.xml new file mode 100644 index 000000000..25d45942b --- /dev/null +++ b/xmldoc/formats/options/text-degformat.xml @@ -0,0 +1,5 @@ + +When GPSBabel writes coordinates, this option is consulted to see if it +should write decimal degrees ('ddd') decimal minutes ('dmm') or degrees, +minutes, seconds ('dms'). The default is 'dmm'. + diff --git a/xmldoc/formats/options/text-encrypt.xml b/xmldoc/formats/options/text-encrypt.xml new file mode 100644 index 000000000..2d7d96091 --- /dev/null +++ b/xmldoc/formats/options/text-encrypt.xml @@ -0,0 +1,3 @@ + +Use this option to encrypt hints from Groundspeak GPX files. + diff --git a/xmldoc/formats/options/text-logs.xml b/xmldoc/formats/options/text-logs.xml new file mode 100644 index 000000000..9e25a13ea --- /dev/null +++ b/xmldoc/formats/options/text-logs.xml @@ -0,0 +1,3 @@ + +Use this option to include Groundspeak cache logs in the created document. + diff --git a/xmldoc/formats/options/text-nosep.xml b/xmldoc/formats/options/text-nosep.xml new file mode 100644 index 000000000..75e79abf7 --- /dev/null +++ b/xmldoc/formats/options/text-nosep.xml @@ -0,0 +1,3 @@ + +To suppress the dashed lines between waypoints, use this option. + diff --git a/xmldoc/formats/options/tiger-genurl.xml b/xmldoc/formats/options/tiger-genurl.xml new file mode 100644 index 000000000..d1bd24f2b --- /dev/null +++ b/xmldoc/formats/options/tiger-genurl.xml @@ -0,0 +1,18 @@ + +genurl is a convenience option for generating the scaling paramaters +when accessing the Tiger servers. It will output the latitude, longitude, +height, and width parameters in a form suitable for use in the URL to generate +a map that will hold all the points to be displayed and is suitably scaled +and centered. + +For example: +gpsbabel -i geo -f geocaching.loc -o tiger,genurl=tiger.ctr -F tiger.dat +may create tiger.ctr with +lat=36.042108&lon=-86.877408&ht=0.161172&wid=0.591771&iwd=768&iht=768 + +After uploading tiger.dat to a public server, a request to + http://tiger.census.gov/cgi-bin/mapgen?murl=$THATFILE$(cat tiger.ctr) +will return a gif file from the tiger server that's suitably scaled. + + + diff --git a/xmldoc/formats/options/tiger-iconismarker.xml b/xmldoc/formats/options/tiger-iconismarker.xml new file mode 100644 index 000000000..899aed557 --- /dev/null +++ b/xmldoc/formats/options/tiger-iconismarker.xml @@ -0,0 +1,4 @@ + This options signifies that the icon in the incoming format is to be used +without change in the generated Tiger output file. Without this option, +GPSBabel tries to color pins based on their creation time and certain +Geocaching traits when available. diff --git a/xmldoc/formats/options/tiger-margin.xml b/xmldoc/formats/options/tiger-margin.xml new file mode 100644 index 000000000..e9b58184a --- /dev/null +++ b/xmldoc/formats/options/tiger-margin.xml @@ -0,0 +1,7 @@ +This option specifies a margin around the maps for the genurl options. +The margin may be specified in either decimal degrees or as a +percentage. + +This option is most useful for ensuring there is adaequate space for +the label around the markers when generating automatically scaled maps. + diff --git a/xmldoc/formats/options/tiger-newmarker.xml b/xmldoc/formats/options/tiger-newmarker.xml new file mode 100644 index 000000000..ec3af7c12 --- /dev/null +++ b/xmldoc/formats/options/tiger-newmarker.xml @@ -0,0 +1,3 @@ +This option specifies the pin to be used if a waypoint has a creation +time older than 'oldthresh' days. +The default is "greenpin". diff --git a/xmldoc/formats/options/tiger-nolabels.xml b/xmldoc/formats/options/tiger-nolabels.xml new file mode 100644 index 000000000..33ec2c1cb --- /dev/null +++ b/xmldoc/formats/options/tiger-nolabels.xml @@ -0,0 +1,3 @@ +This option tells GPSBabel to not generate labels on the pins. If +this is true, the description of the incoming waypoints are ignored and not +placed on the pins. diff --git a/xmldoc/formats/options/tiger-oldmarker.xml b/xmldoc/formats/options/tiger-oldmarker.xml new file mode 100644 index 000000000..abce81d92 --- /dev/null +++ b/xmldoc/formats/options/tiger-oldmarker.xml @@ -0,0 +1,3 @@ +This option specifies the pin to be used if a waypoint has a creation +time newer than 'oldthresh' days. +The default is "redpin". diff --git a/xmldoc/formats/options/tiger-oldthresh.xml b/xmldoc/formats/options/tiger-oldthresh.xml new file mode 100644 index 000000000..919026372 --- /dev/null +++ b/xmldoc/formats/options/tiger-oldthresh.xml @@ -0,0 +1,5 @@ +This options allows you to control the threshold in days between +whether a pin is considered "new" (and thus potentially governed by the +'newmarker' option) or "old" (and thus potentially governed by the +'oldmarker' option). + diff --git a/xmldoc/formats/options/tiger-snlen.xml b/xmldoc/formats/options/tiger-snlen.xml new file mode 100644 index 000000000..ae39cd736 --- /dev/null +++ b/xmldoc/formats/options/tiger-snlen.xml @@ -0,0 +1,5 @@ + +The snlen option controls the maximum length of names generated by the '-s' +option. It's particularly useful in Tiger maps to avoid the amount of clutter +generated by potentially lengthy labels on the markers. + diff --git a/xmldoc/formats/options/tiger-suppresswhite.xml b/xmldoc/formats/options/tiger-suppresswhite.xml new file mode 100644 index 000000000..6576ef45c --- /dev/null +++ b/xmldoc/formats/options/tiger-suppresswhite.xml @@ -0,0 +1,4 @@ + +When set, this options tells the '-s' smartname generator to not allow +any spaces in the labels generated for markers. + diff --git a/xmldoc/formats/options/tiger-unfoundmarker.xml b/xmldoc/formats/options/tiger-unfoundmarker.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/tiger-unfoundmarker.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/tiger-xpixels.xml b/xmldoc/formats/options/tiger-xpixels.xml new file mode 100644 index 000000000..a857af3ed --- /dev/null +++ b/xmldoc/formats/options/tiger-xpixels.xml @@ -0,0 +1,3 @@ +The xpixels argument lets you specify the number of pixels to be +generated by the Tiger server along the horizontal axis when using the +'genurl' option. diff --git a/xmldoc/formats/options/tiger-ypixels.xml b/xmldoc/formats/options/tiger-ypixels.xml new file mode 100644 index 000000000..846de24a4 --- /dev/null +++ b/xmldoc/formats/options/tiger-ypixels.xml @@ -0,0 +1,4 @@ +The ypixels argument lets you specify the number of pixels to be +generated by the Tiger server along the vertical axis when using the +'genurl' option. + diff --git a/xmldoc/formats/options/tpg-datum.xml b/xmldoc/formats/options/tpg-datum.xml new file mode 100644 index 000000000..679556531 --- /dev/null +++ b/xmldoc/formats/options/tpg-datum.xml @@ -0,0 +1,5 @@ + The option 'datum="datum name"' can be used to override +the default of NAD27 ("N. America 1927 mean") which is correct for the +continental U.S. Points in Hawaii should use "Old +Hawaiian_mean" + diff --git a/xmldoc/formats/options/vcard-encrypt.xml b/xmldoc/formats/options/vcard-encrypt.xml new file mode 100644 index 000000000..1ba2851e2 --- /dev/null +++ b/xmldoc/formats/options/vcard-encrypt.xml @@ -0,0 +1,4 @@ + +By default geocaching hints are unencrypted; use this option to encrypt them. + + diff --git a/xmldoc/formats/options/wbt-erase.xml b/xmldoc/formats/options/wbt-erase.xml new file mode 100644 index 000000000..71aaf2c54 --- /dev/null +++ b/xmldoc/formats/options/wbt-erase.xml @@ -0,0 +1 @@ +This option erases the track log from the device after download. \ No newline at end of file diff --git a/xmldoc/formats/options/wfff-ahcicon.xml b/xmldoc/formats/options/wfff-ahcicon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/wfff-ahcicon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/wfff-ahoicon.xml b/xmldoc/formats/options/wfff-ahoicon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/wfff-ahoicon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/wfff-aicicon.xml b/xmldoc/formats/options/wfff-aicicon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/wfff-aicicon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/wfff-aioicon.xml b/xmldoc/formats/options/wfff-aioicon.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/wfff-aioicon.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/wfff-snmac.xml b/xmldoc/formats/options/wfff-snmac.xml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/xmldoc/formats/options/wfff-snmac.xml @@ -0,0 +1 @@ + diff --git a/xmldoc/formats/options/xcsv-prefer_shortnames.xml b/xmldoc/formats/options/xcsv-prefer_shortnames.xml new file mode 100644 index 000000000..e3103bd2d --- /dev/null +++ b/xmldoc/formats/options/xcsv-prefer_shortnames.xml @@ -0,0 +1,7 @@ + +This option causes GPSBabel to use the short name of the waypoint instead +of the description. This overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + diff --git a/xmldoc/formats/options/xcsv-snlen.xml b/xmldoc/formats/options/xcsv-snlen.xml new file mode 100644 index 000000000..9318463ce --- /dev/null +++ b/xmldoc/formats/options/xcsv-snlen.xml @@ -0,0 +1,8 @@ + +This option specifies the maximum allowable length for a short name on +output. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + + diff --git a/xmldoc/formats/options/xcsv-snunique.xml b/xmldoc/formats/options/xcsv-snunique.xml new file mode 100644 index 000000000..1687cbec1 --- /dev/null +++ b/xmldoc/formats/options/xcsv-snunique.xml @@ -0,0 +1,8 @@ + +When this option is specified, GPSBabel will ensure that all short names are +unique within the output file. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + + diff --git a/xmldoc/formats/options/xcsv-snupper.xml b/xmldoc/formats/options/xcsv-snupper.xml new file mode 100644 index 000000000..99400ee91 --- /dev/null +++ b/xmldoc/formats/options/xcsv-snupper.xml @@ -0,0 +1,8 @@ + +When this option is specified, GPSBabel will make all short names contain +only UPPERCASE characters. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + + diff --git a/xmldoc/formats/options/xcsv-snwhite.xml b/xmldoc/formats/options/xcsv-snwhite.xml new file mode 100644 index 000000000..1688f0bc9 --- /dev/null +++ b/xmldoc/formats/options/xcsv-snwhite.xml @@ -0,0 +1,7 @@ + +When this option is specified, GPSBabel will allow whitespace (spaces or tabs) +in generated short names. This option overrides the style file. + + +Valid values for this option are 0 (off) and 1 (on). + diff --git a/xmldoc/formats/options/xcsv-style.xml b/xmldoc/formats/options/xcsv-style.xml new file mode 100644 index 000000000..43baf0378 --- /dev/null +++ b/xmldoc/formats/options/xcsv-style.xml @@ -0,0 +1,10 @@ + +This option specifies the style file that defines the records to be read on +input or written on output. This is not a valid option for the various +built-in xcsv-based styles; they have prebuilt style definitions. + + +For information on the format of xcsv style files, see +. + + diff --git a/xmldoc/formats/options/xcsv-urlbase.xml b/xmldoc/formats/options/xcsv-urlbase.xml new file mode 100644 index 000000000..781e75c4c --- /dev/null +++ b/xmldoc/formats/options/xcsv-urlbase.xml @@ -0,0 +1,5 @@ + +This option specifies the base name to prepend to a URL on output. This +might be useful if an input file contains URLs in a relative format and you +need them to be in an absolute format. + diff --git a/xmldoc/formats/options/yahoo-addrsep.xml b/xmldoc/formats/options/yahoo-addrsep.xml new file mode 100644 index 000000000..249ca3cb4 --- /dev/null +++ b/xmldoc/formats/options/yahoo-addrsep.xml @@ -0,0 +1,9 @@ + +This option specifies the string GPSBabel should use to separate the parts +of the street address. Since most other formats supported by GPSBabel do +not support street addresses, the street address fields from the Yahoo file +are concatenated into the waypoint "notes" field. + + +The default value for this option is a comma followed by a space (", "). + diff --git a/xmldoc/formats/ozi.xml b/xmldoc/formats/ozi.xml new file mode 100644 index 000000000..1e3819a0e --- /dev/null +++ b/xmldoc/formats/ozi.xml @@ -0,0 +1,7 @@ + + + + OziExplorer Waypoint Format - Another CSV format file. +Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex +Mottram + diff --git a/xmldoc/formats/palmdoc.xml b/xmldoc/formats/palmdoc.xml new file mode 100644 index 000000000..5c7a6cf31 --- /dev/null +++ b/xmldoc/formats/palmdoc.xml @@ -0,0 +1,13 @@ + +PalmDoc output is similar to Text +output, except that it generates a Palm Database (PDB) file suitable for +use with programs like CSpotRun, TealDoc, AportisDoc, Palm Reader, and +others. The resulting file also contains bookmarks to make it easy to jump +to a particular waypoint. + + +The following command line reads a GPX file with Groundspeak extensions +and writes a Palm document with encrypted hints and logs: + +gpsbabel -i gpx -f 12345.gpx -o "palmdoc,dbname=Unfound Geocaches,encrypt,logs" -F 12345.pdb + diff --git a/xmldoc/formats/pathaway.xml b/xmldoc/formats/pathaway.xml new file mode 100644 index 000000000..435adff4d --- /dev/null +++ b/xmldoc/formats/pathaway.xml @@ -0,0 +1,10 @@ + + + + PathAway is a Palm software designed for handling "most" +GPS devices (including BlueTooth). In this time (I mean 2005) a free +tool to convert this database is located on the homepage of PathAway +(www.pathaway.com). But I've read there ... for windows and the output +formats are also very limited. + + diff --git a/xmldoc/formats/pcx.xml b/xmldoc/formats/pcx.xml new file mode 100644 index 000000000..428670cae --- /dev/null +++ b/xmldoc/formats/pcx.xml @@ -0,0 +1,13 @@ + + + + Garmin documents only PCX5, an older format limited to +the lame NMEA six-character waypoint names that's treated as a +second-class citizien in current versions of MapSource. In Mapsource, +use file->import to read these files. If you name the files *.wpt, +Mapsource will find them easier. + + In general, you should prefer the "mapsource" file format +to this one. + + diff --git a/xmldoc/formats/psitrex.xml b/xmldoc/formats/psitrex.xml new file mode 100644 index 000000000..b9c59537f --- /dev/null +++ b/xmldoc/formats/psitrex.xml @@ -0,0 +1,10 @@ + + + + This is a text format created by KuDaTa's PsiTrex program +for the Psion PDAs. The format can't be readily handled by XCSV, so +this format is handled explicitly. Waypoints, routes and tracks are +all handled, with icon names used corresponding to verison 1.13 of +PsiTrex. This module was contributed to GPSBabel by Mark +Bradley. + diff --git a/xmldoc/formats/psp.xml b/xmldoc/formats/psp.xml new file mode 100644 index 000000000..6c600418b --- /dev/null +++ b/xmldoc/formats/psp.xml @@ -0,0 +1,223 @@ + +Microsoft's PocketStreets 2002 Pushpin (.PSP) format is +not yet completely documented. The .PSP module does not work with +MS Streets & Trips 2002 .EST files To create .PSP files from +Streets & Trips 2002, you will need to have PocketStreets support +installed. + + +Please note that MS Streets & Trips only exports +.PSP files. It does not import them. MS Streets & Trips 2002 only +imports CSV files. To use .PSP files, simply copy them over to the +same folder on the mobile device as the map (.MPS), and open +PocketStreets. It should also be noted that in the case a pushpin is +outside of the exported map area, the pin will be "grayed-out" and +unused in PocketStreets. This is a good thing as it allows us to +create one big .PSP file that covers multiple .MPS files. +Unfortunately, you need one .PSP file for every .MPS file. + +
              +Frequently Asked Questions + + + + +Why should I use GPSBabel/psp to make pushpins when Streets & Trips (S&T) + already does that for me? + + + + +GPSBabel/psp has the advantage of being able to create pushpins +without + creating the associated map file and the need to "import" the waypoint + data into S&T. Through a series of scripts, you can create a dozen + or so PSP files in a few seconds as opposed to a few weeks using the + S&T interface. The maps are not going to change between sessions, + only the pins will. Why waste all that time creating maps when all you + really want are updated pins? As an aside, GPSBabel/psp creates points + with the proper coordinates + where S&T does not in some areas of the U.S. + (Nashville, TN for instance). + + + + + + +I keep getting a blank (32 byte) PSP file. + + + + +There are either no points to write, or you have botched the command + line for GPSBabel. GPSBabel is sensitive to UPPER and lower case + on the command line. A simple command line to create PSP files + looks like this: + +gpsbabel -i geo -f geocaching.loc -o psp -F NewOrleans.psp + + Note the use of "-f" for INPUT files and "-F" for OUTPUT files. + + + + + + +I've created a PSP file, now what do I do with it? + + + + +To use pushpins in Pocketstreets, you need to have both a map and a + pushpin file. These two files must exist in the same folder and have + exactly the same base name as the map. For example, the pins that + correspond to the map "NewOrleans.mps" should be named "NewOrleans.psp". + + + + + + +I don't have a map. What do I do now? + + + + +Create one using the "Export map to Pocketstreets" option in S&T. You + can also pick up some major city maps on the web from the MS Pocketstreets + website if you are interested in seeing how it works. + + + + + + +I have .EST files, not .PSP files. What's up with that? + + + + +In order to make PSP files, you need to use the "Export map to + Pocketstreets" function in S&T. .EST files are for use in S&T, not + Pocketstreets. + + + + + + + The .PSP files differ when I use GPSBabel/psp versus Pocketstreets to + create them. What's up? + + + + +Pocketstreets makes corrections to the S&T waypoint data upon initial + loading. GPSBabel/psp writes PSP files with these corrections already made. + Ask MS. + + + + + + +Does GPSBabel/psp work with (Autoroute, Mappoint, etc..) .PSP files? + + + + +As of this writing, I haven't seen any so I can't be sure. If they + follow the same layout as S&T 2002, I'd imagine so. + + + + + + + Does GPSBabel/psp work with (S&T 2001, S&T 2002, etc...) files? + + + + +MS changed the file layout between S&T 2001 and S&T 2002. The GPSBabel psp + module is known to work fine with S&T 2002 and 2003. + + + + + + +Does GPSBabel/psp work with (insert your country/location here) maps? + + + + +If it doesn't, feel free to inquire on the +GPSBabel-Misc +mailing list. + + + + + + +What do you mean S&T writes points with the wrong coordinates? + + + + +At some point in the "Export map to Pocketstreets" function in S&T, + it goofs the lat/long data. Points in Nashville tended to shift + 1.4 miles WEST of their original location. I'm not a geometry buff, + but I'd imagine they have a reference point for generating coordinates + that's wrong in (at least) that area. + + + + + + +I have 800 waypoints that cover a dozen or so Pocketstreets maps. + Do I need to to split my points up into smaller chunks to match the + area covered by the maps? + + + + + No. Pocketstreets will "ignore" points that are outside of the map + area. Points that are not on the current map will be "grayed out" + in pushpin explorer in Pocketsreets. This is the reason the PSP + module was written for GPSBabel in the first place. + + + + + + +Where can I find documentation for the layout of PSP files? + + + + +Just about everything I know about the PSP file format is documented + in the source. To the best of my knowledge, there is no documentation + (and for good reason, I've come to discover). + + + + + + +I have some other problem, what do I do? + + + + +Ask your question on the GPSBabel-Misc mailing list. + + + + +
              + diff --git a/xmldoc/formats/quovadis.xml b/xmldoc/formats/quovadis.xml new file mode 100644 index 000000000..516601e76 --- /dev/null +++ b/xmldoc/formats/quovadis.xml @@ -0,0 +1,21 @@ + + + + QuoVadis for Palm OS marcosoft.com is a program for +Palm/OS. Working with record definitions provided by MarcoSoft and +further experimentation by Bruce Thompson and "Fuzzy" from the +Geocaching Forums to nail down the format precisely. + Should work fine for import and export. + One thing of note, QuoVadis stores all waypoints in a +single Palm Database without using categories. This means that it may +be difficult to keep personal waypoints separate from generated +waypoints. What Bruce recommends is taking the QuoVadisMarkerDB.PDB +file synced down from your Palm Powered device and extract the +waypoints you personally set to a GPX file. Then using GPSBabel's +joining capabilities generate a new PDB file from the personal file +and the other waypoint files of interest. + Currently the selection of icons to display and the scale +at which to display them is hardcoded. Also there is no support for +notes associated with waypoints. This will be addressed in a future +revision. + diff --git a/xmldoc/formats/s_and_t.xml b/xmldoc/formats/s_and_t.xml new file mode 100644 index 000000000..ce0e8cc26 --- /dev/null +++ b/xmldoc/formats/s_and_t.xml @@ -0,0 +1,9 @@ + + + + This is a format for importing into Microsoft Streets and +Trips. It's been exercised on versions 2003, 2004, and 2005. Detailed +instructions on how to use it, including preserving hyperlinks, are at +gpsbabel.org + + diff --git a/xmldoc/formats/saplus.xml b/xmldoc/formats/saplus.xml new file mode 100644 index 000000000..4073e0f27 --- /dev/null +++ b/xmldoc/formats/saplus.xml @@ -0,0 +1,17 @@ + + + + This format is for Street Atlas USA 2004 Plus. + + For geocachers importing data from a tool like GSAK or +Spinner, import the file twice in XData. One will create a file with +the Cache description as a hyperlink on the flag. This can clutter up +the screen and when you try to zoom in, it causes problems. So the +second one will only have a flag. Thus you can turn off and on which +one you want to view. The first time you import the file, in the +assign field types, check the circle above Full Name and then next. +The second time you import the file do not check any circle and in the +second to last column, change URL to none and then click next. Use the +same name you used the first time but add -Flag to it. + + diff --git a/xmldoc/formats/saroute.xml b/xmldoc/formats/saroute.xml new file mode 100644 index 000000000..d0db6155c --- /dev/null +++ b/xmldoc/formats/saroute.xml @@ -0,0 +1,9 @@ + +This format reads route files from many Delorme mapping products. +It supports the anr, rte, and rtd formats as either tracks or +routes. + All options only apply to route files from newer (anr) +versions of DeLorme software; older versions didn't store the turn +information with the route. + + diff --git a/xmldoc/formats/sportsim.xml b/xmldoc/formats/sportsim.xml new file mode 100644 index 000000000..2be80258a --- /dev/null +++ b/xmldoc/formats/sportsim.xml @@ -0,0 +1,14 @@ + + With this format we support Sportsim trackfiles located in zipped .ssz archives. + + + Currently we cannot read zipped files directly with GPSBabel. So you have + to extract the archive before you can use any file. The trackfiles have .txt extensions. + + +From the Sportsim homepage: + + + Sportsim provide software applications and web-based graphically + simulated performance information and image solutions to outdoor active people. + diff --git a/xmldoc/formats/stmsdf.xml b/xmldoc/formats/stmsdf.xml new file mode 100644 index 000000000..e01b49768 --- /dev/null +++ b/xmldoc/formats/stmsdf.xml @@ -0,0 +1,23 @@ + + This format supports the .sdf files from the Suunto product family + 'Suunto Trek Manager', 'Suunto Ski Manager' and 'Suunto Sail Manager'. + The contents of the sdf file depends on the used product and can + be one route or one track. Thatswhy when you want to use sdf on the + output side you have to use the + -r OR the -t option. This will tell + GPSBabel which type of data should be written. + + + Currently we can read the following file types: + + 4 = M9 TrackLog + 5 = Route + 28 = X9 TrackLog + + + + gpsbabel -i gpx -f some-routes.gpx -r -o stmsdf,index=3 -F single-route.sdf + + + Suunto Website + diff --git a/xmldoc/formats/stmwpp.xml b/xmldoc/formats/stmwpp.xml new file mode 100644 index 000000000..e7129e7db --- /dev/null +++ b/xmldoc/formats/stmwpp.xml @@ -0,0 +1,10 @@ + +This format supports the Suunto Trek Manager (STM) WaypointPlus format. +This is a simple format with coordinates and a time stamp. Route points +also have a short name. A single file may only contain one route or one +track. + + +Suunto Website + + diff --git a/xmldoc/formats/tabsep.xml b/xmldoc/formats/tabsep.xml new file mode 100644 index 000000000..04f7d1fcf --- /dev/null +++ b/xmldoc/formats/tabsep.xml @@ -0,0 +1,12 @@ + +This format, like the custom format, is +mainly used for the purpose of testing GPSBabel. It is supposed to contain +one field for each piece of information supported by the +xcsv format writer, but it may not be entirely +in sync with the documentation at . + + +For a list of fields, see the style/tabsep.style file in the GPSBabel source +distribution. + + diff --git a/xmldoc/formats/tef.xml b/xmldoc/formats/tef.xml new file mode 100644 index 000000000..40e5855b2 --- /dev/null +++ b/xmldoc/formats/tef.xml @@ -0,0 +1,15 @@ + +TEF, internally called "TourExchangeFormat", is an XML based export format +used by Map&Guide Motorrad-Routenplaner 2005/06. + + +Because this is only an export format, GPSBabel does not support writing to +this format. + + +GPSBabel also supports the bcr format, which +may also be used with this program and supports both reading and writing. + + + gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx + diff --git a/xmldoc/formats/text.xml b/xmldoc/formats/text.xml new file mode 100644 index 000000000..1e2952c59 --- /dev/null +++ b/xmldoc/formats/text.xml @@ -0,0 +1,8 @@ + This is a simple human readable version of the data file, +handy for listings of any type of waypoint files. + + The following command line reads a GPX file with +Groundspeak extensions and writes a text file with encrypted hints: + +gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt + diff --git a/xmldoc/formats/tiger.xml b/xmldoc/formats/tiger.xml new file mode 100644 index 000000000..0a736c0d2 --- /dev/null +++ b/xmldoc/formats/tiger.xml @@ -0,0 +1,9 @@ + + + + The U.S. Census Bureau provides online mapping facilities. +This format is described at: tiger.census.gov. +Do notice that this format is not the actual Tiger line mapping +records, but rather the interface to their online mapping +program. + diff --git a/xmldoc/formats/tmpro.xml b/xmldoc/formats/tmpro.xml new file mode 100644 index 000000000..ee5457bd4 --- /dev/null +++ b/xmldoc/formats/tmpro.xml @@ -0,0 +1,10 @@ + + + + TopoMapPro Places File. Reads and writes places files for +use in TopoMapPro topomappro.com). As this file +type can store links other than web links, anything that is not a http +url will be discarded. Note that this does not do datum conversions, +so if your input file does not have WGS84/NZGD2000 data, your output +file won't either. Colour of waypoint icons defaults to red. + diff --git a/xmldoc/formats/tomtom.xml b/xmldoc/formats/tomtom.xml new file mode 100644 index 000000000..cb9b94726 --- /dev/null +++ b/xmldoc/formats/tomtom.xml @@ -0,0 +1,15 @@ + + + + This format can read and write TomTom .ov2 (POI) files, +as used by the TomTom GO and TomTom Navigator. It has been tested +with an original TomTom GO running version 5.00 of the TomTom +software. There may be some records that confuse the input module - +if you have an example of such a record "in the wild", and you aren't +restricted from sharing it, we encourage you to post to the +gpsbabel-misc mailing list to contact a developer. + Note that in addition to the .ov2 file, you will need a +.bmp file for the icon. It should be 22x22 and 16 colors, and have +the same name (not including the extension) as the .ov2 file. + + diff --git a/xmldoc/formats/tpg.xml b/xmldoc/formats/tpg.xml new file mode 100644 index 000000000..68cbada63 --- /dev/null +++ b/xmldoc/formats/tpg.xml @@ -0,0 +1,8 @@ + + + + National Geographic Topo! Waypoint and Route Format. This module +reads and writes .TPG files created by various editions of NG Topo! +Reading/writing of route data is not supported yet. +Contributed by Alex Mottram. + diff --git a/xmldoc/formats/tpo.xml b/xmldoc/formats/tpo.xml new file mode 100644 index 000000000..9b9149dfd --- /dev/null +++ b/xmldoc/formats/tpo.xml @@ -0,0 +1,12 @@ + + + + This module reads .TPO files created by various editions +of NG Topo!. For version 2.x files it will only read tracks. For +version 3.x files it will read Tracks/Routes/Waypoints/Map +Notes/Symbols/Text Notes. The latter three are converted to +waypoints. + 2.x support contributed by Steve Chamberlin. 3.x support +contributed by Curt Mills. + + diff --git a/xmldoc/formats/tpo2.xml b/xmldoc/formats/tpo2.xml new file mode 100644 index 000000000..fe1cde696 --- /dev/null +++ b/xmldoc/formats/tpo2.xml @@ -0,0 +1,9 @@ + + This module reads tracks from .TPO files created by + National Geographic Topo! version 2.x + + + Contributed by Steve Chamberlin. + + + diff --git a/xmldoc/formats/tpo3.xml b/xmldoc/formats/tpo3.xml new file mode 100644 index 000000000..ce5d0ff40 --- /dev/null +++ b/xmldoc/formats/tpo3.xml @@ -0,0 +1,6 @@ +This module reads .TPO files created by National Geographic Topo! version +3.x and 4.x. It will read tracks, routes, waypoints, map notes, symbols, and +text notes. The latter three are converted to waypoints. + +Contributed by Curt Mills. + diff --git a/xmldoc/formats/unicsv.xml b/xmldoc/formats/unicsv.xml new file mode 100644 index 000000000..6b7a21bba --- /dev/null +++ b/xmldoc/formats/unicsv.xml @@ -0,0 +1,26 @@ + + + + + Unicsv examines the first line of a file to determine the field + order and field separator in that file. It is thus read-only format. + + + If the first line contains any tabs, the data lines are assumed + to be tab separated. Otherwise the fields are assumed to be + separated by commas. + + + The list of keywords include "lat", "lon", "desc", "name", + "notes", "alt", "utm z", "utm n", "utm e", and "url". + Fuller spellings (i.e. "longitude") may be used. + + + A typical file may be: + + Name, Latitude, Longitude, Description + GCEBB,35.972033,-87.134700,Mountain Bike Heaven by susy1313 + GC1A37,36.090683,-86.679550,The Troll by a182pilot & Family + + + diff --git a/xmldoc/formats/vcard.xml b/xmldoc/formats/vcard.xml new file mode 100644 index 000000000..f365dadb0 --- /dev/null +++ b/xmldoc/formats/vcard.xml @@ -0,0 +1,13 @@ + + + + The vCard output is intended to be in a format that +enables waypoints to be viewed with an Apple iPod. This is achieved by +mapping waypoint fields into vCard fields that can be displayed as +'Contacts' on the iPod. With the iPod mounted as a hard disk (see your +iPod manual for instructions), the resulting VCF file should be moved +into the iPod 'Contacts' folder. As an alternative, Mac OS X users may +prefer to drag the VCF file into their address book and synchronize +with the iPod using iSync. + + diff --git a/xmldoc/formats/vitosmt.xml b/xmldoc/formats/vitosmt.xml new file mode 100644 index 000000000..31b80dd4f --- /dev/null +++ b/xmldoc/formats/vitosmt.xml @@ -0,0 +1,10 @@ + + + + Vito Navigator II is a Pocket PC GPS application. This +format reads a Vito Navigator II .SMT track file and can work in +either waypoint or track mode. The speed, heading and Dilution of +Position data is written in the notes field. + Support for writing .SMT tracks is very experimental and +may crash VitoNavigator II on the Pocket PC. + diff --git a/xmldoc/formats/wbt-bin.xml b/xmldoc/formats/wbt-bin.xml new file mode 100644 index 000000000..f1c49475d --- /dev/null +++ b/xmldoc/formats/wbt-bin.xml @@ -0,0 +1,12 @@ +File protocol for the Wintec WBT-200 +GPS data logger. This format reads the binary file format created +by Wintec's Windows application. + +Wintec WBT-200 + + + Command showing conversion of a Wintec binary file to GPX + gpsbabel -i wbt-bin -f tracks.bin -o +gpx -F out.gpx + + diff --git a/xmldoc/formats/wbt.xml b/xmldoc/formats/wbt.xml new file mode 100644 index 000000000..215f0fea1 --- /dev/null +++ b/xmldoc/formats/wbt.xml @@ -0,0 +1,9 @@ +Serial download protocol for the Wintec WBT-200 GPS data logger. Although untested it is expected that this will also support the WBT-100. + +Wintec WBT-200 + + + Command showing WBT-200 download and erase over Bluetooth on Mac OS X + gpsbabel -i wbt,erase -f /dev/cu.WBT200-SPPslave-1 -o gpx -F out.gpx + + diff --git a/xmldoc/formats/wfff.xml b/xmldoc/formats/wfff.xml new file mode 100644 index 000000000..5e808900e --- /dev/null +++ b/xmldoc/formats/wfff.xml @@ -0,0 +1,7 @@ + + + + WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs. + It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session. + All WiFi-specific elements are written in the description field, similar to the netstumbler format. + diff --git a/xmldoc/formats/xcsv.xml b/xmldoc/formats/xcsv.xml new file mode 100644 index 000000000..cc2e9e2ab --- /dev/null +++ b/xmldoc/formats/xcsv.xml @@ -0,0 +1,14 @@ + +This format is a very flexible module that can be used to read or write +nearly any plain-text record-based waypoint file. This flexibility is +achieved by combining this format with "style" files that describe the +format of the waypoint files. + + +There are several formats built in to GPSBabel that use the underlying xcsv +machinery. Each of those formats takes the same options as the xcsv format, +with the obvious exception of the option. +Those formats are all based on style files that can be found in +the "style" directory in the GPSBabel source distribution. + + diff --git a/xmldoc/formats/xmap.xml b/xmldoc/formats/xmap.xml new file mode 100644 index 000000000..2032e560b --- /dev/null +++ b/xmldoc/formats/xmap.xml @@ -0,0 +1,9 @@ + + + + Delorme TopoUSA/XMap Conduit is one of the billion CSV +variants mentioned above. It's just like S&A with the addition of +a completely pointless line at the beginning and end of the file. This +is the format used to hot-sync to XMap from withing TopoUSA. Done with +help of Dan Edwards. + diff --git a/xmldoc/formats/xmap2006.xml b/xmldoc/formats/xmap2006.xml new file mode 100644 index 000000000..06d591937 --- /dev/null +++ b/xmldoc/formats/xmap2006.xml @@ -0,0 +1,10 @@ + + + + Delorme XMap2006 Conduit is just like XMap, except there are + no spaces between fields and the coordinate format is slightly + different. The completely pointless header and footer lines + are the same, at least. Use this to create the XMapHHWptsSend.txt + file needed to sync to Street Atlas Handheld 2006. + Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file. + diff --git a/xmldoc/formats/xmapwpt.xml b/xmldoc/formats/xmapwpt.xml new file mode 100644 index 000000000..cbd2481e1 --- /dev/null +++ b/xmldoc/formats/xmapwpt.xml @@ -0,0 +1,77 @@ + +Delorme XMapHandHeld Street Atlas USA is another of the +billion CSV variants. This is the format used by XmapHH SA USA on (at +least) PocketPC O/S. + + +This XMap is not the same as the simpler +XMap format, which is used with Topo USA 4.0 +and XMapHH for Palm. + + +Delorme XMap Handheld .WPT for PocketPC is a bit of a kludge. This +chapter covers XMap Handheld Street Atlas USA edition. + + +XMap on the PocketPC stores its waypoints in individual .wpt files. +For example, waypoints generated by XMap on the PocketPC are stored +by default in the "My Documents" folder using the sequential names +"XMap1.wpt", "XMap2.wpt", ad nauseum. Needless to say, this is not very +efficient. + + +As writing multiple waypoint files is outside of the scope of GPSBabel, +GPSBabel chooses to write one big file, one waypoint per line. +Extracting lines from this file is left as an exercise for the end user. +A simple Perl script to handle this conversion is included at the end +of this chapter. + + +It should also be noted that reading multiple files +is indeed possible, but if you have more than a few points, it can be a task. +For example: + +gpsbabel -i xmapwpt -f Xmap1.wpt -f Xmap2.wpt -o mapsend -F mapsend.wpt + +will read the two Xmap .wpt files and write one mapsend file. This +is fine for a small handful of points, but could be quite cumbersome +for folks like me who have 100+ waypoints loaded into XMap. For *nix +folks, something as simple as: + +cat *.wpt > /tmp/foo.wpt +gpsbabel -i xmapwpt -f foo.wpt -o mapsend -F mapsend.wpt + +will do the trick just fine. + + +#!/full/path/to/perl +$INPUTFILE = @ARGV[0]; +$TARGETDIR = @ARGV[1]; +$FILENAME = @ARGV[2]; + +if (! $FILENAME) { + print "Usage: xmap_split.pl INPUT_FILE OUTPUT_DIRECTORY FILENAME_BASE\n"; + print " (i.e. xmapl_split.pl points.wpt /tmp/points GPSB)\n"; + print " (created GPSB0001-GPSBXXXX in /tmp/points/ from points.wpt)\n"; + exit; +} + +open (INFILE, $INPUTFILE) || die "Cannot open $INPUTFILE for read!\n"; + +while (<INFILE>) { + $lc++; + $filename = sprintf("%s/Gpsb%04d.wpt", $TARGETDIR, $lc); + + open (OUTFILE, ">$filename") || die "Cannot open $filename for write!\n"; + + print OUTFILE $_; + + close(OUTFILE); +} + +exit; + + + +Contributed to GPSBabel by Alex Mottram. + diff --git a/xmldoc/formats/yahoo.xml b/xmldoc/formats/yahoo.xml new file mode 100644 index 000000000..af379358d --- /dev/null +++ b/xmldoc/formats/yahoo.xml @@ -0,0 +1,7 @@ + +This format reads output from the +Yahoo geocoding API. +This feature of GPSBabel makes it easy to get geocoded results from +Yahoo into your favorite mapping program, GPS receiver, or other format. + + diff --git a/xmldoc/gpsbabel_man.xml b/xmldoc/gpsbabel_man.xml new file mode 100644 index 000000000..e0842df80 --- /dev/null +++ b/xmldoc/gpsbabel_man.xml @@ -0,0 +1,81 @@ + + + + +gpsbabel +1 + + + +gpsbabel + + convert and manipulate waypoints, tracks, and routes between formats. + + + + + +gpsbabel + + + +file + + + +Description + +GPSBabel converts waypoints, tracks, and routes from one format to another, whether that format is a common mapping format like Delorme, Streets and Trips, or even a serial upload or download to a GPS unit such as those from Garmin and Magellan. By flattening the Tower of Babel that the authors of various programs for manipulating GPS data have imposed upon us, it returns to us the ability to freely move our own waypoint data between the programs and hardware we choose to use. + +It contains extensive data manipulation abilities making it a convenient for server-side processing or as the backend for other tools. + + + +Options + + GPSBabel accepts the following options and processes them in order + from left to right.. Additional options are documented in the + docbook help. + + + + format + Use format as the type file to read. + + + name + Use name as the filename to read. + + + format + Use format as the type of file to read. + + + name + Use name as the filename to write. + + + filter + Invoke an internal filter on the data. + + + + Generate smart names for waypoints on output. + + + format + Display help that is more exhaustive than this page. If format is given, provide help for only that format. + + +Lists of filters and formats are given in the doc at http://www.gpsbabel.org. + + +See Also + + http://www.gpsbabel.org + + + + + diff --git a/xmldoc/makedoc.in b/xmldoc/makedoc.in new file mode 100644 index 000000000..cf3b354ea --- /dev/null +++ b/xmldoc/makedoc.in @@ -0,0 +1,217 @@ +#!/usr/bin/perl + +# +# makedoc.in is used to generate makedoc. +# + +sub expandrw { + my $read = shift; + my $write = shift; + my $type = shift; + + my $res = ""; + if ( ($read eq 'r') || ($write eq 'w')) { + $res .= " \n \n "; + if ( ($read eq 'r') && ($write eq 'w')) { + $res .= "read and write $type"; + } + elsif ( $read eq 'r' ) { + $res .= "read $type"; + } + elsif ( $write eq 'w' ) { + $res .= "write $type"; + } + $res .= "\n \n \n"; + } + $res; +} + +sub expandoptions { + my $opts = shift; + my $res = " \n This format can...\n \n"; + + $res .= expandrw( substr($opts,0,1), substr($opts,1,1), 'waypoints' ); + $res .= expandrw( substr($opts,2,1), substr($opts,3,1), 'tracks' ); + $res .= expandrw( substr($opts,4,1), substr($opts,5,1), 'routes' ); + + $res .= " \n \n"; + + $res; +} + +sub include { + my $name=shift; + my $dir2=shift; + + $name2 = $name; + $name2 =~ s/-/_/g; + $d2 = $dir2; + $d2 =~ s:/.*::; + $name2 = $d2.'_'.$name2; + print PARTS qq(\n); + print FILE "\&inc_$name2;\n"; + if (! -e "$dir/$dir2/$name.xml") { + open TMP, ">$dir/$dir2/$name.xml"; + print TMP "\n"; + close TMP; + } +} + +sub includef { + my $name=shift; + + $name2 = $name; + $name2 =~ s/-/_/g; + print PARTS qq(\n); + print FORMATS "\&inc_$name2;\n"; +} + + + +@dir=`mkdir -p @DOCDIR@`; +$dir = $0; +$dir =~ s:/.*$::; + + +open PARTS, ">$dir/autogen/_parts.xml"; +print PARTS qq(\n); +print PARTS qq(\n); +print PARTS qq(\n); + +open FORMATS, ">$dir/autogen/_formats.xml"; +print FORMATS qq(\n); + +@formats = `./gpsbabel -^3`; + +$going = 0; +$dooptions = 0; + + +for (@formats) { + chomp; + s/\&/\&/g; + s//\>/g; + @line = split "\t"; + + if ( $line[0] eq 'internal') { + if ($going) { + print FILE "

4K*R8T&6_?)e$IT$ZrmR}EVoi)cch!p3 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ॹ*BeQ7Pe(*7h>1Z$%iadHPN|{3vqjVyP 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

oYS4Od8gfUA53l^?Kh-P%)PB@YZ&W8=+sJLC}M zE4FfAG+gnAs}xeW%KkLtmIa2Zd~3E{b;-oh^a>0c5Fn>~1+_VBW2fB#l>@D*KW|F` z!*z#TtKGK~h<4U2Nz8g{*37_RSH6PUS0DhQk?So`yAB(`S8svZi?DEge{uI3321sP z+)G@zGB8*Sn|h0y;VKIZ*S8H5UxCuA_}Q$jV!&{nHB-{A`pP7DIgqA?JH3vEEB5{t zsLuimSLYLw`$T}@su{x%>~A5p2Yg1umDF-T9;jjdlAa%+^lBWm^`8(lz1nikhNoAC R2F!3}U + + + + + + + 320.000000 + + + + 320.000000 + + + + 320.100006 + + + + 320.100006 + + + + 320.100006 + + + + 320.100006 + + + + 320.100006 + + + + 320.200012 + + + + 320.200012 + + + + 320.299988 + + + + 320.600006 + + + + 321.000000 + + + + + diff --git a/reference/track/compegps-trk.gpx b/reference/track/compegps-trk.gpx new file mode 100644 index 000000000..06456e1d7 --- /dev/null +++ b/reference/track/compegps-trk.gpx @@ -0,0 +1,183 @@ + + + + + + ACTIVE LOG 006 + + + 161.000000 + + + + 154.000000 + + + + 148.000000 + + + + 139.000000 + + + + 145.000000 + + + + 134.000000 + + + + 131.000000 + + + + 130.000000 + + + + 132.000000 + + + + 144.000000 + + + + 147.000000 + + + + 145.000000 + + + + 145.000000 + + + + 135.000000 + + + + 135.000000 + + + + 136.000000 + + + + 135.000000 + + + + 139.000000 + + + + 139.000000 + + + + 141.000000 + + + + 140.000000 + + + + 140.000000 + + + + 152.000000 + + + + 152.000000 + + + + 155.000000 + + + + 149.000000 + + + + 150.000000 + + + + 151.000000 + + + + 151.000000 + + + + 150.000000 + + + + 150.000000 + + + + 150.000000 + + + + 150.000000 + + + + 143.000000 + + + + 141.000000 + + + + 143.000000 + + + + 139.000000 + + + + 139.000000 + + + + 138.000000 + + + + 139.000000 + + + + 144.000000 + + + + 145.000000 + + + + + diff --git a/reference/track/compegps.trk b/reference/track/compegps.trk new file mode 100644 index 000000000..dc0c04f09 --- /dev/null +++ b/reference/track/compegps.trk @@ -0,0 +1,53 @@ +G WGS 84 +U 1 +N oliskoli +D Leipzig +C 119 119 0 2 -1.000000 +L 02:00:00 +V 0.0 0.0 0 0 0 0 0.0 +M No comment +E 0|1|00-NUL-00 00:00:00|00:00:00|0 +T A 51.3129500000ºN 12.4131666667ºE 01-MAY-05 13:02:47 N 161.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +t 4294967295|ACTIVE LOG 006|-1|-1 +T A 51.3128833333ºN 12.4132333333ºE 01-MAY-05 13:03:25 s 154.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128666667ºN 12.4132333333ºE 01-MAY-05 13:03:39 s 148.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128166667ºN 12.4133000000ºE 01-MAY-05 13:04:16 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128333333ºN 12.4132666667ºE 01-MAY-05 13:05:02 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128333333ºN 12.4133166667ºE 01-MAY-05 13:05:45 s 134.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3127833333ºN 12.4133500000ºE 01-MAY-05 13:06:44 s 131.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3127833333ºN 12.4133333333ºE 01-MAY-05 13:07:50 s 130.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3127500000ºN 12.4133333333ºE 01-MAY-05 13:08:19 s 132.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3128166667ºN 12.4133166667ºE 01-MAY-05 13:11:16 s 144.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129333333ºN 12.4134500000ºE 01-MAY-05 13:12:34 s 147.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130000000ºN 12.4138000000ºE 01-MAY-05 13:13:18 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130500000ºN 12.4138166667ºE 01-MAY-05 13:13:27 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130500000ºN 12.4138500000ºE 01-MAY-05 13:13:37 s 135.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131166667ºN 12.4138500000ºE 01-MAY-05 13:13:46 s 135.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3132166667ºN 12.4138833333ºE 01-MAY-05 13:14:03 s 136.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3133000000ºN 12.4139666667ºE 01-MAY-05 13:14:16 s 135.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3132833333ºN 12.4140500000ºE 01-MAY-05 13:14:26 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3132666667ºN 12.4141000000ºE 01-MAY-05 13:14:30 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3130500000ºN 12.4146166667ºE 01-MAY-05 13:15:06 s 141.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129833333ºN 12.4148333333ºE 01-MAY-05 13:15:27 s 140.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129333333ºN 12.4149333333ºE 01-MAY-05 13:15:39 s 140.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129500000ºN 12.4149666667ºE 01-MAY-05 13:25:31 s 152.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129333333ºN 12.4149833333ºE 01-MAY-05 13:25:40 s 152.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3129666667ºN 12.4149500000ºE 01-MAY-05 13:29:18 s 155.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131666667ºN 12.4146000000ºE 01-MAY-05 13:30:30 s 149.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131666667ºN 12.4145666667ºE 01-MAY-05 13:30:37 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131666667ºN 12.4144333333ºE 01-MAY-05 13:30:47 s 151.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3131500000ºN 12.4143833333ºE 01-MAY-05 13:30:48 s 151.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3133333333ºN 12.4139000000ºE 01-MAY-05 13:30:52 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3137000000ºN 12.4133166667ºE 01-MAY-05 13:30:57 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3139833333ºN 12.4128666667ºE 01-MAY-05 13:31:03 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3142166667ºN 12.4124833333ºE 01-MAY-05 13:31:10 s 150.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4095666667ºE 01-MAY-05 13:32:38 s 143.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4095000000ºE 01-MAY-05 13:32:45 s 141.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4095000000ºE 01-MAY-05 13:33:17 s 143.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4094500000ºE 01-MAY-05 13:33:42 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:33:54 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:34:04 s 138.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:34:20 s 139.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:35:45 s 144.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +T A 51.3146500000ºN 12.4093500000ºE 01-MAY-05 13:35:56 s 145.0 0.0 0.0 0.0 0 -1000.0 -1.0 -1.0 -1.0 +F 1234 diff --git a/reference/track/dmtlog-sample.gpx b/reference/track/dmtlog-sample.gpx new file mode 100644 index 000000000..fc52a5c6f --- /dev/null +++ b/reference/track/dmtlog-sample.gpx @@ -0,0 +1,669 @@ + + + + + + 44.586548 + 5066 + 5066 + 5066 + + + 57.607200 + 5067 + 5067 + 5067 + + + 44.826904 + 5096 + 5096 + 5096 + + + 50.594727 + 5142 + 5142 + 5142 + + + 127.711200 + 5156 + 5156 + 5156 + + + 96.926400 + 5224 + 5224 + 5224 + + + 82.600800 + 5229 + 5229 + 5229 + + + 82.905600 + 5237 + 5237 + 5237 + + + 66.696655 + 5254 + 5254 + 5254 + + + 74.627442 + 5258 + 5258 + 5258 + + + 65.254761 + 5264 + 5264 + 5264 + + + 77.419200 + 526708 + 526708 + 526708 + + + 74.676000 + 526750 + 526750 + 526750 + + + 78.713135 + 527614 + 527614 + 527614 + + + 78.713135 + 527631 + 527631 + 527631 + + + 68.275200 + 5278 + 5278 + 5278 + + + 64.008000 + 5289 + 5289 + 5289 + + + 52.997925 + 5374FIRE + 5374FIRE + 5374FIRE + + + 56.388000 + 5376 + 5376 + 5376 + + + 56.388000 + 6006 + 600698 + 600698 + + + 46.028564 + 6006BLUE + 6006BLUE + 6006BLUE + + + 37.616943 + 6014MEADOW + 6014MEADOW + 6014MEADOW + + + 56.388000 + 6029 + 6029 + 6029 + + + 50.292000 + 6053 + 6053 + 6053 + + + 25.603200 + 6066 + 6066 + 6066 + + + 34.442400 + 6067 + 6067 + 6067 + + + 30.480000 + 6071 + 6071 + 6071 + + + 15.240000 + 6073 + 6073 + 6073 + + + 37.795200 + 6084 + 6084 + 6084 + + + 64.008000 + 6130 + 6130 + 6130 + + + 64.008000 + 6131 + 6131 + 6131 + + + 62.788800 + 6153 + 6153 + 6153 + + + 55.473600 + 6171 + 6171 + 6171 + + + 62.484000 + 6176 + 6176 + 6176 + + + 62.179200 + 6177 + 6177 + 6177 + + + 69.799200 + 6272 + 6272 + 6272 + + + 73.152000 + 6272 + 6272 + 6272 + + + 70.104000 + 6278 + 6278 + 6278 + + + 57.564209 + 6280 + 6280 + 6280 + + + 66.696655 + 6283 + 6283 + 6283 + + + 72.945191 + 6289 + 6289 + 6289 + + + 72.847200 + 6297 + 6297 + 6297 + + + 53.644800 + 6328 + 6328 + 6328 + + + 43.891200 + 6354 + 6354 + 6354 + + + 48.768000 + 635722 + 635722 + 635722 + + + 49.072800 + 635783 + 635783 + 635783 + + + 62.484000 + 6373 + 6373 + 6373 + + + 3.962400 + 6634 + 6634 + 6634 + + + 13.411200 + 6979 + 6979 + 6979 + + + 34.012085 + 6997 + 6997 + 6997 + + + 87.782400 + BEAR HILL + BEAR HILL TOWER + BEAR HILL TOWER + + + 23.469600 + BELLEVUE + BELLEVUE + BELLEVUE + + + 43.384766 + 6016 + Bike Loop Connector + Bike Loop Connector + + + 89.916000 + 5236BRIDGE + Bridge + Bridge + + + 55.473600 + 5376BRIDGE + Bridge + Bridge + + + 52.730400 + 6181CROSS + Crossing + Crossing + + + 45.110400 + 6042CROSS + Crossing + Crossing + + + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + + + 56.083200 + 6121DEAD + Dead End + Dead End + + + 117.043200 + 5179DEAD + Dead End + Dead End + + + 69.494400 + 5299DEAD + Dead End + Dead End + + + 56.997600 + 5376DEAD + Dead End + Dead End + + + 46.939200 + 6353DEAD + Dead End + Dead End + + + 61.264800 + 6155DEAD + Dead End + Dead End + + + 110.947200 + GATE14 + Gate 14 + Gate 14 + + + 77.724000 + GATE16 + Gate 16 + Gate 16 + + + 65.836800 + GATE17 + Gate 17 + Gate 17 + + + 57.302400 + GATE19 + Gate 19 + Gate 19 + + + 49.377600 + GATE21 + Gate 21 + Gate 21 + + + 81.076800 + GATE24 + Gate 24 + Gate 24 + + + 21.515015 + GATE5 + Gate 5 + Gate 5 + + + 26.561890 + GATE6 + Gate 6 + Gate 6 + + + 32.004000 + 6077LOGS + Log Crossing + Log Crossing + + + 119.809082 + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + + + 73.761600 + 5267OBSTAC + Obstacle + Obstacle + + + 45.307495 + PANTHRCAVE + Panther Cave + Panther Cave + + + 77.992066 + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + + + 67.970400 + 5287WATER + Reservoir + Reservoir + + + 81.076800 + 5239ROAD + Road + Road + + + 67.360800 + 5278ROAD + Road + Road + + + 53.949600 + 5058ROAD + ROAD CROSSING + ROAD CROSSING + + + 69.799200 + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + + + 64.008000 + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + + + 64.533692 + 5376STREAM + Stream Crossing + Stream Crossing + + + 61.649902 + 5144SUMMIT + Summit + Summit + + + 67.360800 + 5150TANK + WATER TANK + WATER TANK + + + + + 1.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2.000000 + + + + + 1.000000 + + + + + + + + + + + 2.000000 + + + 1.000000 + + + 1.000000 + + + + + 2.000000 + + + + + + + + + + + + + 6.000000 + + + 2.000000 + + + + + + + + + + + 1.000000 + + + + + + + 6.000000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 7.000000 + + + + + + + + + + + + + + + + + + diff --git a/reference/track/fugawi.txt b/reference/track/fugawi.txt index 8bca8dc50..ba8237891 100644 --- a/reference/track/fugawi.txt +++ b/reference/track/fugawi.txt @@ -8,67 +8,67 @@ # Latitude in Degree and decimals (soutern hemisphere has neg. degrees) # Longitude in degree and decimals (neg. numbers: west of Greenwich) # Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS -RPT001,RPT001,,30.0621833,-91.6103500,1.0 ,20020525,170621 -RPT002,RPT002,,30.0627833,-91.6105667,0.0 ,20020525,170955 -RPT003,RPT003,,30.0627000,-91.6082667,0.0 ,20020525,171200 -RPT004,RPT004,,30.0623333,-91.6073833,0.0 ,20020525,171248 -RPT005,RPT005,,30.0615333,-91.6052833,0.0 ,20020525,171441 -RPT006,RPT006,,30.0597833,-91.5994000,0.0 ,20020525,171716 -RPT007,RPT007,,30.0578000,-91.5966833,0.0 ,20020525,171746 -RPT008,RPT008,,30.0553833,-91.5949000,0.0 ,20020525,171820 -RPT009,RPT009,,30.0538833,-91.5926167,0.0 ,20020525,171901 -RPT010,RPT010,,30.0497333,-91.5897500,0.0 ,20020525,172046 -RPT011,RPT011,,30.0490167,-91.5898833,0.0 ,20020525,172110 -RPT012,RPT012,,30.0488000,-91.5929333,0.0 ,20020525,172151 -RPT013,RPT013,,30.0462333,-91.5964500,0.0 ,20020525,172235 -RPT014,RPT014,,30.0455167,-91.5987167,0.0 ,20020525,172308 -RPT015,RPT015,,30.0473000,-91.6002667,0.0 ,20020525,180423 -RPT016,RPT016,,30.0470000,-91.5996333,2.0 ,20020525,180604 -RPT017,RPT017,,30.0464333,-91.5994667,0.0 ,20020525,180706 -RPT018,RPT018,,30.0462000,-91.5989500,1.0 ,20020525,180818 -RPT019,RPT019,,30.0463667,-91.5977333,0.0 ,20020525,181020 -RPT020,RPT020,,30.0463500,-91.5971667,0.0 ,20020525,181109 -RPT021,RPT021,,30.0467833,-91.5963333,0.0 ,20020525,181218 -RPT022,RPT022,,30.0474500,-91.5952000,0.0 ,20020525,181422 -RPT023,RPT023,,30.0478000,-91.5947667,2.0 ,20020525,181504 -RPT024,RPT024,,30.0482500,-91.5940833,1.0 ,20020525,181614 -RPT025,RPT025,,30.0486833,-91.5938000,1.0 ,20020525,181701 -RPT026,RPT026,,30.0493500,-91.5938500,0.0 ,20020525,181807 -RPT027,RPT027,,30.0503167,-91.5939833,2.0 ,20020525,181951 -RPT028,RPT028,,30.0507833,-91.5941167,0.0 ,20020525,182039 -RPT029,RPT029,,30.0512333,-91.5943667,0.0 ,20020525,182124 -RPT030,RPT030,,30.0518000,-91.5943667,0.0 ,20020525,182217 -RPT031,RPT031,,30.0522167,-91.5946667,0.0 ,20020525,182318 -RPT032,RPT032,,30.0530167,-91.5946833,0.0 ,20020525,182437 -RPT033,RPT033,,30.0548667,-91.5952000,6.0 ,20020525,182813 -RPT034,RPT034,,30.0537333,-91.5949333,2.0 ,20020525,183136 -RPT035,RPT035,,30.0531833,-91.5947833,0.0 ,20020525,183256 -RPT036,RPT036,,30.0526333,-91.5948333,0.0 ,20020525,183402 -RPT037,RPT037,,30.0524500,-91.5954333,0.0 ,20020525,183603 -RPT038,RPT038,,30.0524833,-91.5959667,0.0 ,20020525,183648 -RPT039,RPT039,,30.0526500,-91.5967833,1.0 ,20020525,183752 -RPT040,RPT040,,30.0531333,-91.5978500,0.0 ,20020525,183918 -RPT041,RPT041,,30.0536167,-91.5979667,0.0 ,20020525,184015 -RPT042,RPT042,,30.0539667,-91.5977667,6.0 ,20020525,184125 -RPT043,RPT043,,30.0536167,-91.5980833,0.0 ,20020525,184237 -RPT044,RPT044,,30.0532000,-91.5979167,0.0 ,20020525,184401 -RPT045,RPT045,,30.0528167,-91.5975167,0.0 ,20020525,184553 -RPT046,RPT046,,30.0525667,-91.5969333,0.0 ,20020525,184654 -RPT047,RPT047,,30.0523333,-91.5964333,0.0 ,20020525,184742 -RPT048,RPT048,,30.0522500,-91.5956833,0.0 ,20020525,184841 -RPT049,RPT049,,30.0522167,-91.5950167,0.0 ,20020525,184952 -RPT050,RPT050,,30.0518833,-91.5947000,0.0 ,20020525,185049 -RPT051,RPT051,,30.0510500,-91.5944000,0.0 ,20020525,185214 -RPT052,RPT052,,30.0505667,-91.5942333,0.0 ,20020525,185256 -RPT053,RPT053,,30.0501833,-91.5941000,0.0 ,20020525,185338 -RPT054,RPT054,,30.0491000,-91.5937167,0.0 ,20020525,185511 -RPT055,RPT055,,30.0484500,-91.5942500,0.0 ,20020525,185632 -RPT056,RPT056,,30.0480833,-91.5947500,0.0 ,20020525,185724 -RPT057,RPT057,,30.0475000,-91.5954500,7.0 ,20020525,185840 -RPT058,RPT058,,30.0470667,-91.5960000,0.0 ,20020525,185928 -RPT059,RPT059,,30.0466333,-91.5966000,0.0 ,20020525,190022 -RPT060,RPT060,,30.0464000,-91.5976500,0.0 ,20020525,190141 -RPT061,RPT061,,30.0462333,-91.5984667,0.0 ,20020525,190248 -RPT062,RPT062,,30.0463167,-91.5989667,0.0 ,20020525,190343 -RPT063,RPT063,,30.0467833,-91.5992833,0.0 ,20020525,190449 -RPT064,RPT064,,30.0471333,-91.5996667,0.0 ,20020525,190557 +,,,30.0621833,-91.6103500,1.0 ,20020525,170621 +,,,30.0627833,-91.6105667,0.0 ,20020525,170955 +,,,30.0627000,-91.6082667,0.0 ,20020525,171200 +,,,30.0623333,-91.6073833,0.0 ,20020525,171248 +,,,30.0615333,-91.6052833,0.0 ,20020525,171441 +,,,30.0597833,-91.5994000,0.0 ,20020525,171716 +,,,30.0578000,-91.5966833,0.0 ,20020525,171746 +,,,30.0553833,-91.5949000,0.0 ,20020525,171820 +,,,30.0538833,-91.5926167,0.0 ,20020525,171901 +,,,30.0497333,-91.5897500,0.0 ,20020525,172046 +,,,30.0490167,-91.5898833,0.0 ,20020525,172110 +,,,30.0488000,-91.5929333,0.0 ,20020525,172151 +,,,30.0462333,-91.5964500,0.0 ,20020525,172235 +,,,30.0455167,-91.5987167,0.0 ,20020525,172308 +,,,30.0473000,-91.6002667,0.0 ,20020525,180423 +,,,30.0470000,-91.5996333,2.0 ,20020525,180604 +,,,30.0464333,-91.5994667,0.0 ,20020525,180706 +,,,30.0462000,-91.5989500,1.0 ,20020525,180818 +,,,30.0463667,-91.5977333,0.0 ,20020525,181020 +,,,30.0463500,-91.5971667,0.0 ,20020525,181109 +,,,30.0467833,-91.5963333,0.0 ,20020525,181218 +,,,30.0474500,-91.5952000,0.0 ,20020525,181422 +,,,30.0478000,-91.5947667,2.0 ,20020525,181504 +,,,30.0482500,-91.5940833,1.0 ,20020525,181614 +,,,30.0486833,-91.5938000,1.0 ,20020525,181701 +,,,30.0493500,-91.5938500,0.0 ,20020525,181807 +,,,30.0503167,-91.5939833,2.0 ,20020525,181951 +,,,30.0507833,-91.5941167,0.0 ,20020525,182039 +,,,30.0512333,-91.5943667,0.0 ,20020525,182124 +,,,30.0518000,-91.5943667,0.0 ,20020525,182217 +,,,30.0522167,-91.5946667,0.0 ,20020525,182318 +,,,30.0530167,-91.5946833,0.0 ,20020525,182437 +,,,30.0548667,-91.5952000,6.0 ,20020525,182813 +,,,30.0537333,-91.5949333,2.0 ,20020525,183136 +,,,30.0531833,-91.5947833,0.0 ,20020525,183256 +,,,30.0526333,-91.5948333,0.0 ,20020525,183402 +,,,30.0524500,-91.5954333,0.0 ,20020525,183603 +,,,30.0524833,-91.5959667,0.0 ,20020525,183648 +,,,30.0526500,-91.5967833,1.0 ,20020525,183752 +,,,30.0531333,-91.5978500,0.0 ,20020525,183918 +,,,30.0536167,-91.5979667,0.0 ,20020525,184015 +,,,30.0539667,-91.5977667,6.0 ,20020525,184125 +,,,30.0536167,-91.5980833,0.0 ,20020525,184237 +,,,30.0532000,-91.5979167,0.0 ,20020525,184401 +,,,30.0528167,-91.5975167,0.0 ,20020525,184553 +,,,30.0525667,-91.5969333,0.0 ,20020525,184654 +,,,30.0523333,-91.5964333,0.0 ,20020525,184742 +,,,30.0522500,-91.5956833,0.0 ,20020525,184841 +,,,30.0522167,-91.5950167,0.0 ,20020525,184952 +,,,30.0518833,-91.5947000,0.0 ,20020525,185049 +,,,30.0510500,-91.5944000,0.0 ,20020525,185214 +,,,30.0505667,-91.5942333,0.0 ,20020525,185256 +,,,30.0501833,-91.5941000,0.0 ,20020525,185338 +,,,30.0491000,-91.5937167,0.0 ,20020525,185511 +,,,30.0484500,-91.5942500,0.0 ,20020525,185632 +,,,30.0480833,-91.5947500,0.0 ,20020525,185724 +,,,30.0475000,-91.5954500,7.0 ,20020525,185840 +,,,30.0470667,-91.5960000,0.0 ,20020525,185928 +,,,30.0466333,-91.5966000,0.0 ,20020525,190022 +,,,30.0464000,-91.5976500,0.0 ,20020525,190141 +,,,30.0462333,-91.5984667,0.0 ,20020525,190248 +,,,30.0463167,-91.5989667,0.0 ,20020525,190343 +,,,30.0467833,-91.5992833,0.0 ,20020525,190449 +,,,30.0471333,-91.5996667,0.0 ,20020525,190557 diff --git a/reference/track/i65.anr.gpx b/reference/track/i65.anr.gpx index 041709c92..f6788b614 100644 --- a/reference/track/i65.anr.gpx +++ b/reference/track/i65.anr.gpx @@ -1,4971 +1,4971 @@ - + - - + + Home to 8520 Northwe + Local Road + + \00000 \00001 - + \00002 \00003 - - \00004 - - \00005 + \00004 - \00006 + I-65 N - \00007 + \00005 - \00008 + \00006 - \00009 + \00007 - \0000a + \00008 - \0000b + \00009 - \0000c + \0000a - \0000d + \0000b - \0000e + \0000c - \0000f + \0000d - \00010 + \0000e - \00011 + \0000f - \00012 + \00010 - \00013 + \00011 - \00014 + \00012 - \00015 + \00013 - \00016 + \00014 - \00017 + \00015 - \00018 + \00016 - \00019 + \00017 - \0001a + \00018 - \0001b + \00019 - \0001c + \0001a - \0001d + \0001b - \0001e + \0001c - \0001f + \0001d - \00020 + \0001e - \00021 + \0001f - \00022 + \00020 - \00023 + \00021 - \00024 + \00022 - \00025 + \00023 - \00026 + \00024 - \00027 + \00025 - \00028 + \00026 - \00029 + \00027 - \0002a + \00028 - \0002b + \00029 - \0002c + \0002a - \0002d + \0002b - \0002e + \0002c - \0002f + \0002d - \00030 + \0002e - \00031 + \0002f - \00032 + \00030 - \00033 + \00031 - \00034 + \00032 - \00035 + \00033 - \00036 + \00034 - \00037 + \00035 - \00038 + \00036 - \00039 + \00037 - \0003a + \00038 - \0003b + \00039 - \0003c + \0003a - \0003d + \0003b - \0003e + \0003c - \0003f + \0003d - \00040 + \0003e - \00041 + \0003f - \00042 + \00040 - \00043 + \00041 - \00044 + \00042 - \00045 + \00043 - \00046 + \00044 - \00047 + \00045 - \00048 + \00046 - \00049 + \00047 - \0004a + \00048 - \0004b + \00049 - \0004c + \0004a - \0004d + \0004b - \0004e + \0004c - \0004f + \0004d - \00050 + \0004e - \00051 + \0004f - \00052 + \00050 - \00053 + \00051 - \00054 + \00052 - \00055 + \00053 - \00056 + \00054 - \00057 + \00055 - \00058 + \00056 - \00059 + \00057 - \0005a + \00058 - \0005b + \00059 - \0005c + \0005a - \0005d + \0005b - \0005e + \0005c - \0005f + \0005d - \00060 + \0005e - \00061 + \0005f - \00062 + \00060 - \00063 + \00061 - \00064 + \00062 - \00065 + \00063 - \00066 + \00064 - \00067 + \00065 - \00068 + \00066 - \00069 + \00067 - \0006a + \00068 - \0006b + \00069 - \0006c + \0006a - \0006d + \0006b - \0006e + I-40 E (I-65 N) Ramp - \0006f + \0006c - \00070 + \0006d - \00071 + \0006e - \00072 + I-40 E (I-65 N) - \00073 + \0006f - \00074 + \00070 - \00075 + \00071 - \00076 + \00072 - \00077 + \00073 - \00078 + \00074 - \00079 + \00075 - \0007a + \00076 - \0007b + \00077 - \0007c + \00078 - \0007d + I-24 W (I-65 N) Ramp - \0007e + \00079 - \0007f + \0007a - \00080 + \0007b - \00081 + \0007c - \00082 + \0007d - \00083 + I-24 W (I-65 N) - \00084 + \0007e - \00085 + \0007f - \00086 + \00080 - \00087 + \00081 - \00088 + \00082 - \00089 + \00083 - \0008a + \00084 - \0008b + \00085 - \0008c + \00086 - \0008d + \00087 - \0008e + \00088 - \0008f + \00089 - \00090 + \0008a - \00091 + \0008b - \00092 + \0008c - \00093 + \0008d - \00094 + \0008e - \00095 + \0008f - \00096 + \00090 - \00097 + \00091 - \00098 + \00092 - \00099 + \00093 - \0009a + \00094 - \0009b + \00095 - \0009c + \00096 - \0009d + \00097 - \0009e + \00098 - \0009f + \00099 - \000a0 + \0009a - \000a1 + \0009b - \000a2 + \0009c - \000a3 + \0009d - \000a4 + \0009e - \000a5 + \0009f - \000a6 + \000a0 - \000a7 + \000a1 - \000a8 + \000a2 - \000a9 + \000a3 - \000aa + \000a4 - \000ab + \000a5 - \000ac + \000a6 - \000ad + I-65 N - \000ae + \000a7 - \000af + \000a8 - \000b0 + \000a9 - \000b1 + \000aa - \000b2 + \000ab - \000b3 + \000ac - \000b4 + \000ad - \000b5 + \000ae - \000b6 + \000af - \000b7 + \000b0 - \000b8 + \000b1 - \000b9 + \000b2 - \000ba + \000b3 - \000bb + \000b4 - \000bc + \000b5 - \000bd + \000b6 - \000be + \000b7 - \000bf + \000b8 - \000c0 + \000b9 - \000c1 + \000ba - \000c2 + \000bb - \000c3 + \000bc - \000c4 + \000bd - \000c5 + \000be - \000c6 + \000bf - \000c7 + \000c0 - \000c8 + \000c1 - \000c9 + \000c2 - \000ca + \000c3 - \000cb + \000c4 - \000cc + \000c5 - \000cd + \000c6 - \000ce + \000c7 - \000cf + \000c8 - \000d0 + \000c9 - \000d1 + \000ca - \000d2 + \000cb - \000d3 + \000cc - \000d4 + \000cd - \000d5 + \000ce - \000d6 + \000cf - \000d7 + \000d0 - \000d8 + \000d1 - \000d9 + \000d2 - \000da + \000d3 - \000db + \000d4 - \000dc + \000d5 - \000dd + \000d6 - \000de + \000d7 - \000df + \000d8 - \000e0 + \000d9 - \000e1 + \000da - \000e2 + \000db - \000e3 + \000dc - \000e4 + \000dd - \000e5 + \000de - \000e6 + \000df - \000e7 + \000e0 - \000e8 + \000e1 - \000e9 + \000e2 - \000ea + \000e3 - \000eb + \000e4 - \000ec + \000e5 - \000ed + \000e6 - \000ee + \000e7 - \000ef + \000e8 - \000f0 + \000e9 - \000f1 + \000ea - \000f2 + \000eb - \000f3 + \000ec - \000f4 + \000ed - \000f5 + \000ee - \000f6 + \000ef - \000f7 + \000f0 - \000f8 + \000f1 - \000f9 + \000f2 - \000fa + \000f3 - \000fb + \000f4 - \000fc + \000f5 - \000fd + \000f6 - \000fe + \000f7 - \000ff + \000f8 - \00100 + \000f9 - \00101 + \000fa - \00102 + \000fb - \00103 + \000fc - \00104 + \000fd - \00105 + \000fe - \00106 + \000ff - \00107 + \00100 - \00108 + \00101 - \00109 + \00102 - \0010a + \00103 - \0010b + \00104 - \0010c + \00105 - \0010d + \00106 - \0010e + \00107 - \0010f + \00108 - \00110 + \00109 - \00111 + \0010a - \00112 + \0010b - \00113 + \0010c - \00114 + \0010d - \00115 + \0010e - \00116 + \0010f - \00117 + \00110 - \00118 + \00111 - \00119 + \00112 - \0011a + \00113 - \0011b + \00114 - \0011c + \00115 - \0011d + \00116 - \0011e + \00117 - \0011f + \00118 - \00120 + \00119 - \00121 + \0011a - \00122 + \0011b - \00123 + \0011c - \00124 + \0011d - \00125 + \0011e - \00126 + \0011f - \00127 + \00120 - \00128 + \00121 - \00129 + \00122 - \0012a + \00123 - \0012b + \00124 - \0012c + \00125 - \0012d + \00126 - \0012e + \00127 - \0012f + \00128 - \00130 + \00129 - \00131 + \0012a - \00132 + \0012b - \00133 + \0012c - \00134 + \0012d - \00135 + \0012e - \00136 + \0012f - \00137 + \00130 - \00138 + \00131 - \00139 + \00132 - \0013a + \00133 - \0013b + \00134 - \0013c + \00135 - \0013d + \00136 - \0013e + \00137 - \0013f + \00138 - \00140 + \00139 - \00141 + \0013a - \00142 + \0013b - \00143 + \0013c - \00144 + \0013d - \00145 + \0013e - \00146 + \0013f - \00147 + \00140 - \00148 + \00141 - \00149 + \00142 - \0014a + \00143 - \0014b + \00144 - \0014c + \00145 - \0014d + \00146 - \0014e + \00147 - \0014f + \00148 - \00150 + \00149 - \00151 + \0014a - \00152 + \0014b - \00153 + \0014c - \00154 + \0014d - \00155 + \0014e - \00156 + \0014f - \00157 + \00150 - \00158 + \00151 - \00159 + \00152 - \0015a + \00153 - \0015b + \00154 - \0015c + \00155 - \0015d + \00156 - \0015e + \00157 - \0015f + \00158 - \00160 + \00159 - \00161 + \0015a - \00162 + \0015b - \00163 + \0015c - \00164 + \0015d - \00165 + \0015e - \00166 + \0015f - \00167 + \00160 - \00168 + \00161 - \00169 + \00162 - \0016a + \00163 - \0016b + \00164 - \0016c + \00165 - \0016d + \00166 - \0016e + \00167 - \0016f + \00168 - \00170 + \00169 - \00171 + \0016a - \00172 + \0016b - \00173 + \0016c - \00174 + \0016d - \00175 + \0016e - \00176 + \0016f - \00177 + \00170 - \00178 + \00171 - \00179 + \00172 - \0017a + \00173 - \0017b + \00174 - \0017c + \00175 - \0017d + \00176 - \0017e + \00177 - \0017f + \00178 - \00180 + \00179 - \00181 + \0017a - \00182 + \0017b - \00183 + \0017c - \00184 + \0017d - \00185 + \0017e - \00186 + \0017f - \00187 + \00180 - \00188 + \00181 - \00189 + \00182 - \0018a + \00183 - \0018b + \00184 - \0018c + \00185 - \0018d + \00186 - \0018e + \00187 - \0018f + \00188 - \00190 + \00189 - \00191 + \0018a - \00192 + \0018b - \00193 + \0018c - \00194 + \0018d - \00195 + \0018e - \00196 + \0018f - \00197 + \00190 - \00198 + \00191 - \00199 + \00192 - \0019a + \00193 - \0019b + \00194 - \0019c + \00195 - \0019d + \00196 - \0019e + \00197 - \0019f + \00198 - \001a0 + \00199 - \001a1 + \0019a - \001a2 + \0019b - \001a3 + \0019c - \001a4 + \0019d - \001a5 + \0019e - \001a6 + \0019f - \001a7 + \001a0 - \001a8 + \001a1 - \001a9 + \001a2 - \001aa + \001a3 - \001ab + \001a4 - \001ac + \001a5 - \001ad + \001a6 - \001ae + \001a7 - \001af + \001a8 - \001b0 + \001a9 - \001b1 + \001aa - \001b2 + \001ab - \001b3 + \001ac - \001b4 + \001ad - \001b5 + \001ae - \001b6 + \001af - \001b7 + \001b0 - \001b8 + \001b1 - \001b9 + \001b2 - \001ba + \001b3 - \001bb + \001b4 - \001bc + \001b5 - \001bd + \001b6 - \001be + \001b7 - \001bf + \001b8 - \001c0 + \001b9 - \001c1 + \001ba - \001c2 + \001bb - \001c3 + \001bc - \001c4 + \001bd - \001c5 + \001be - \001c6 + \001bf - \001c7 + \001c0 - \001c8 + \001c1 - \001c9 + \001c2 - \001ca + \001c3 - \001cb + \001c4 - \001cc + \001c5 - \001cd + \001c6 - \001ce + \001c7 - \001cf + \001c8 - \001d0 + \001c9 - \001d1 + \001ca - \001d2 + \001cb - \001d3 + \001cc - \001d4 + \001cd - \001d5 + \001ce - \001d6 + \001cf - \001d7 + \001d0 - \001d8 + \001d1 - \001d9 + \001d2 - \001da + \001d3 - \001db + \001d4 - \001dc + \001d5 - \001dd + \001d6 - \001de + \001d7 - \001df + \001d8 - \001e0 + \001d9 - \001e1 + \001da - \001e2 + \001db - \001e3 + \001dc - \001e4 + \001dd - \001e5 + \001de - \001e6 + \001df - \001e7 + \001e0 - \001e8 + \001e1 - \001e9 + \001e2 - \001ea + \001e3 - \001eb + \001e4 - \001ec + \001e5 - \001ed + \001e6 - \001ee + \001e7 - \001ef + \001e8 - \001f0 + \001e9 - \001f1 + \001ea - \001f2 + \001eb - \001f3 + \001ec - \001f4 + \001ed - \001f5 + \001ee - \001f6 + \001ef - \001f7 + \001f0 - \001f8 + \001f1 - \001f9 + \001f2 - \001fa + \001f3 - \001fb + \001f4 - \001fc + \001f5 - \001fd + \001f6 - \001fe + \001f7 - \001ff + \001f8 - \00200 + \001f9 - \00201 + \001fa - \00202 + \001fb - \00203 + \001fc - \00204 + \001fd - \00205 + \001fe - \00206 + \001ff - \00207 + \00200 - \00208 + \00201 - \00209 + \00202 - \0020a + \00203 - \0020b + \00204 - \0020c + \00205 - \0020d + \00206 - \0020e + \00207 - \0020f + \00208 - \00210 + \00209 - \00211 + \0020a - \00212 + \0020b - \00213 + \0020c - \00214 + \0020d - \00215 + \0020e - \00216 + \0020f - \00217 + \00210 - \00218 + \00211 - \00219 + \00212 - \0021a + \00213 - \0021b + \00214 - \0021c + \00215 - \0021d + \00216 - \0021e + \00217 - \0021f + \00218 - \00220 + \00219 - \00221 + \0021a - \00222 + \0021b - \00223 + \0021c - \00224 + \0021d - \00225 + \0021e - \00226 + \0021f - \00227 + \00220 - \00228 + \00221 - \00229 + \00222 - \0022a + \00223 - \0022b + \00224 - \0022c + \00225 - \0022d + \00226 - \0022e + \00227 - \0022f + \00228 - \00230 + \00229 - \00231 + \0022a - \00232 + \0022b - \00233 + \0022c - \00234 + \0022d - \00235 + \0022e - \00236 + \0022f - \00237 + \00230 - \00238 + \00231 - \00239 + \00232 - \0023a + \00233 - \0023b + \00234 - \0023c + \00235 - \0023d + \00236 - \0023e + \00237 - \0023f + \00238 - \00240 + \00239 - \00241 + \0023a - \00242 + \0023b - \00243 + \0023c - \00244 + \0023d - \00245 + \0023e - \00246 + \0023f - \00247 + \00240 - \00248 + \00241 - \00249 + \00242 - \0024a + \00243 - \0024b + \00244 - \0024c + \00245 - \0024d + \00246 - \0024e + \00247 - \0024f + \00248 - \00250 + \00249 - \00251 + \0024a - \00252 + \0024b - \00253 + \0024c - \00254 + \0024d - \00255 + \0024e - \00256 + \0024f - \00257 + \00250 - \00258 + \00251 - \00259 + \00252 - \0025a + \00253 - \0025b + \00254 - \0025c + \00255 - \0025d + \00256 - \0025e + \00257 - \0025f + \00258 - \00260 + \00259 - \00261 + \0025a - \00262 + \0025b - \00263 + \0025c - \00264 + \0025d - \00265 + \0025e - \00266 + \0025f - \00267 + \00260 - \00268 + \00261 - \00269 + \00262 - \0026a + \00263 - \0026b + \00264 - \0026c + \00265 - \0026d + \00266 - \0026e + \00267 - \0026f + \00268 - \00270 + \00269 - \00271 + \0026a - \00272 + \0026b - \00273 + \0026c - \00274 + \0026d - \00275 + \0026e - \00276 + \0026f - \00277 + \00270 - \00278 + \00271 - \00279 + \00272 - \0027a + \00273 - \0027b + \00274 - \0027c + \00275 - \0027d + \00276 - \0027e + \00277 - \0027f + \00278 - \00280 + \00279 - \00281 + \0027a - \00282 + \0027b - \00283 + \0027c - \00284 + \0027d - \00285 + \0027e - \00286 + \0027f - \00287 + \00280 - \00288 + \00281 - \00289 + \00282 - \0028a + \00283 - \0028b + \00284 - \0028c + \00285 - \0028d + \00286 - \0028e + \00287 - \0028f + \00288 - \00290 + \00289 - \00291 + \0028a - \00292 + \0028b - \00293 + \0028c - \00294 + \0028d - \00295 + \0028e - \00296 + \0028f - \00297 + \00290 - \00298 + \00291 - \00299 + \00292 - \0029a + \00293 - \0029b + \00294 - \0029c + \00295 - \0029d + \00296 - \0029e + \00297 - \0029f + \00298 - \002a0 + \00299 - \002a1 + \0029a - \002a2 + \0029b - \002a3 + \0029c - \002a4 + \0029d - \002a5 + \0029e - \002a6 + \0029f - \002a7 + \002a0 - \002a8 + \002a1 - \002a9 + \002a2 - \002aa + \002a3 - \002ab + \002a4 - \002ac + \002a5 - \002ad + \002a6 - \002ae + \002a7 - \002af + \002a8 - \002b0 + \002a9 - \002b1 + \002aa - \002b2 + \002ab - \002b3 + \002ac - \002b4 + \002ad - \002b5 + \002ae - \002b6 + \002af - \002b7 + \002b0 - \002b8 + \002b1 - \002b9 + \002b2 - \002ba + \002b3 - \002bb + \002b4 - \002bc + \002b5 - \002bd + \002b6 - \002be + \002b7 - \002bf + \002b8 - \002c0 + \002b9 - \002c1 + \002ba - \002c2 + \002bb - \002c3 + \002bc - \002c4 + \002bd - \002c5 + \002be - \002c6 + \002bf - \002c7 + \002c0 - \002c8 + \002c1 - \002c9 + \002c2 - \002ca + \002c3 - \002cb + \002c4 - \002cc + \002c5 - \002cd + \002c6 - \002ce + \002c7 - \002cf + \002c8 - \002d0 + \002c9 - \002d1 + \002ca - \002d2 + \002cb - \002d3 + \002cc - \002d4 + \002cd - \002d5 + \002ce - \002d6 + \002cf - \002d7 + \002d0 - \002d8 + \002d1 - \002d9 + \002d2 - \002da + \002d3 - \002db + \002d4 - \002dc + \002d5 - \002dd + \002d6 - \002de + \002d7 - \002df + \002d8 - \002e0 + \002d9 - \002e1 + \002da - \002e2 + \002db - \002e3 + \002dc - \002e4 + \002dd - \002e5 + \002de - \002e6 + \002df - \002e7 + \002e0 - \002e8 + \002e1 - \002e9 + \002e2 - \002ea + \002e3 - \002eb + \002e4 - \002ec + \002e5 - \002ed + \002e6 - \002ee + \002e7 - \002ef + \002e8 - \002f0 + \002e9 - \002f1 + \002ea - \002f2 + \002eb - \002f3 + \002ec - \002f4 + \002ed - \002f5 + \002ee - \002f6 + \002ef - \002f7 + \002f0 - \002f8 + \002f1 - \002f9 + \002f2 - \002fa + \002f3 - \002fb + \002f4 - \002fc + \002f5 - \002fd + \002f6 - \002fe + \002f7 - \002ff + \002f8 - \00300 + \002f9 - \00301 + \002fa - \00302 + \002fb - \00303 + \002fc - \00304 + \002fd - \00305 + \002fe - \00306 + \002ff - \00307 + \00300 - \00308 + \00301 - \00309 + \00302 - \0030a + \00303 - \0030b + \00304 - \0030c + \00305 - \0030d + \00306 - \0030e + \00307 - \0030f + \00308 - \00310 + \00309 - \00311 + \0030a - \00312 + \0030b - \00313 + \0030c - \00314 + \0030d - \00315 + \0030e - \00316 + \0030f - \00317 + \00310 - \00318 + \00311 - \00319 + \00312 - \0031a + \00313 - \0031b + \00314 - \0031c + \00315 - \0031d + \00316 - \0031e + \00317 - \0031f + \00318 - \00320 + \00319 - \00321 + \0031a - \00322 + \0031b - \00323 + \0031c - \00324 + \0031d - \00325 + \0031e - \00326 + \0031f - \00327 + \00320 - \00328 + \00321 - \00329 + \00322 - \0032a + \00323 - \0032b + \00324 - \0032c + \00325 - \0032d + \00326 - \0032e + \00327 - \0032f + \00328 - \00330 + \00329 - \00331 + \0032a - \00332 + \0032b - \00333 + \0032c - \00334 + \0032d - \00335 + \0032e - \00336 + \0032f - \00337 + \00330 - \00338 + \00331 - \00339 + \00332 - \0033a + \00333 - \0033b + \00334 - \0033c + \00335 - \0033d + \00336 - \0033e + \00337 - \0033f + \00338 - \00340 + \00339 - \00341 + \0033a - \00342 + \0033b - \00343 + \0033c - \00344 + \0033d - \00345 + \0033e - \00346 + \0033f - \00347 + \00340 - \00348 + \00341 - \00349 + \00342 - \0034a + \00343 - \0034b + \00344 - \0034c + \00345 - \0034d + \00346 - \0034e + \00347 - \0034f + \00348 - \00350 + \00349 - \00351 + \0034a - \00352 + \0034b - \00353 + \0034c - \00354 + \0034d - \00355 + \0034e - \00356 + \0034f - \00357 + \00350 - \00358 + \00351 - \00359 + \00352 - \0035a + \00353 - \0035b + \00354 - \0035c + \00355 - \0035d + \00356 - \0035e + \00357 - \0035f + \00358 - \00360 + \00359 - \00361 + \0035a - \00362 + \0035b - \00363 + \0035c - \00364 + \0035d - \00365 + \0035e - \00366 + \0035f - \00367 + \00360 - \00368 + \00361 - \00369 + \00362 - \0036a + \00363 - \0036b + \00364 - \0036c + \00365 - \0036d + \00366 - \0036e + \00367 - \0036f + \00368 - \00370 + \00369 - \00371 + \0036a - \00372 + \0036b - \00373 + \0036c - \00374 + \0036d - \00375 + \0036e - \00376 + \0036f - \00377 + \00370 - \00378 + \00371 - \00379 + \00372 - \0037a + \00373 - \0037b + \00374 - \0037c + \00375 - \0037d + \00376 - \0037e + \00377 - \0037f + \00378 - \00380 + \00379 - \00381 + \0037a - \00382 + \0037b - \00383 + \0037c - \00384 + \0037d - \00385 + \0037e - \00386 + \0037f - \00387 + \00380 - \00388 + \00381 - \00389 + \00382 - \0038a + \00383 - \0038b + \00384 - \0038c + \00385 - \0038d + \00386 - \0038e + \00387 - \0038f + \00388 - \00390 + \00389 - \00391 + \0038a - \00392 + \0038b - \00393 + \0038c - \00394 + \0038d - \00395 + \0038e - \00396 + \0038f - \00397 + \00390 - \00398 + \00391 - \00399 + \00392 - \0039a + \00393 - \0039b + \00394 - \0039c + \00395 - \0039d + \00396 - \0039e + \00397 - \0039f + \00398 - \003a0 + \00399 - \003a1 + \0039a - \003a2 + \0039b - \003a3 + \0039c - \003a4 + \0039d - \003a5 + \0039e - \003a6 + \0039f - \003a7 + \003a0 - \003a8 + \003a1 - \003a9 + \003a2 - \003aa + \003a3 - \003ab + \003a4 - \003ac + \003a5 - \003ad + \003a6 - \003ae + \003a7 - \003af + \003a8 - \003b0 + \003a9 - \003b1 + \003aa - \003b2 + \003ab - \003b3 + \003ac - \003b4 + \003ad - \003b5 + \003ae - \003b6 + \003af - \003b7 + \003b0 - \003b8 + \003b1 - \003b9 + \003b2 - \003ba + \003b3 - \003bb + \003b4 - \003bc + \003b5 - \003bd + \003b6 - \003be + \003b7 - \003bf + \003b8 - \003c0 + \003b9 - \003c1 + \003ba - \003c2 + \003bb - \003c3 + \003bc - \003c4 + \003bd - \003c5 + \003be - \003c6 + \003bf - \003c7 + \003c0 - \003c8 + \003c1 - \003c9 + \003c2 - \003ca + \003c3 - \003cb + \003c4 - \003cc + \003c5 - \003cd + \003c6 - \003ce + \003c7 - \003cf + \003c8 - \003d0 + \003c9 - \003d1 + \003ca - \003d2 + \003cb - \003d3 + \003cc - \003d4 + \003cd - \003d5 + \003ce - \003d6 + \003cf - \003d7 + \003d0 - \003d8 + \003d1 - \003d9 + \003d2 - \003da + \003d3 - \003db + \003d4 - \003dc + \003d5 - \003dd + \003d6 - \003de + \003d7 - \003df + \003d8 - \003e0 + \003d9 - \003e1 + \003da - \003e2 + \003db - \003e3 + \003dc - \003e4 + \003dd - \003e5 + \003de - \003e6 + \003df - \003e7 + \003e0 - \003e8 + \003e1 - \003e9 + \003e2 - \003ea + \003e3 - \003eb + \003e4 - \003ec + \003e5 - \003ed + \003e6 - \003ee + \003e7 - \003ef + \003e8 - \003f0 + \003e9 - \003f1 + \003ea - \003f2 + \003eb - \003f3 + \003ec - \003f4 + \003ed - \003f5 + \003ee - \003f6 + \003ef - \003f7 + \003f0 - \003f8 + \003f1 - \003f9 + \003f2 - \003fa + \003f3 - \003fb + \003f4 - \003fc + \003f5 - \003fd + \003f6 - \003fe + \003f7 - \003ff + \003f8 - \00400 + \003f9 - \00401 + \003fa - \00402 + \003fb - \00403 + \003fc - \00404 + \003fd - \00405 + \003fe - \00406 + \003ff - \00407 + \00400 - \00408 + \00401 - \00409 + \00402 - \0040a + \00403 - \0040b + \00404 - \0040c + \00405 - \0040d + \00406 - \0040e + \00407 - \0040f + \00408 - \00410 + \00409 - \00411 + \0040a - \00412 + \0040b - \00413 + \0040c - \00414 + \0040d - \00415 + \0040e - \00416 + \0040f - \00417 + \00410 - \00418 + \00411 - \00419 + \00412 - \0041a + \00413 - \0041b + \00414 - \0041c + \00415 - \0041d + \00416 - \0041e + \00417 - \0041f + \00418 - \00420 + \00419 - \00421 + \0041a - \00422 + \0041b - \00423 + \0041c - \00424 + \0041d - \00425 + \0041e - \00426 + \0041f - \00427 + \00420 - \00428 + \00421 - \00429 + \00422 - \0042a + \00423 - \0042b + \00424 - \0042c + \00425 - \0042d + \00426 - \0042e + \00427 - \0042f + \00428 - \00430 + \00429 - \00431 + \0042a - \00432 + \0042b - \00433 + \0042c - \00434 + \0042d - \00435 + \0042e - \00436 + \0042f - \00437 + \00430 - \00438 + \00431 - \00439 + \00432 - \0043a + \00433 - \0043b + \00434 - \0043c + \00435 - \0043d + \00436 - \0043e + \00437 - \0043f + \00438 - \00440 + \00439 - \00441 + \0043a - \00442 + \0043b - \00443 + \0043c - \00444 + \0043d - \00445 + \0043e - \00446 + \0043f - \00447 + \00440 - \00448 + \00441 - \00449 + \00442 - \0044a + \00443 - \0044b + \00444 - \0044c + \00445 - \0044d + \00446 - \0044e + \00447 - \0044f + \00448 - \00450 + \00449 - \00451 + \0044a - \00452 + \0044b - \00453 + \0044c - \00454 + \0044d - \00455 + \0044e - \00456 + \0044f - \00457 + \00450 - \00458 + \00451 - \00459 + \00452 - \0045a + \00453 - \0045b + \00454 - \0045c + \00455 - \0045d + \00456 - \0045e + \00457 - \0045f + \00458 - \00460 + \00459 - \00461 + \0045a - \00462 + \0045b - \00463 + \0045c - \00464 + \0045d - \00465 + \0045e - \00466 + \0045f - \00467 + \00460 - \00468 + \00461 - \00469 + \00462 - \0046a + \00463 - \0046b + \00464 - \0046c + \00465 - \0046d + \00466 - \0046e + \00467 - \0046f + \00468 - \00470 + \00469 - \00471 + \0046a - \00472 + \0046b - \00473 + \0046c - \00474 + \0046d - \00475 + \0046e - \00476 + \0046f - \00477 + \00470 - \00478 + \00471 - \00479 + \00472 - \0047a + \00473 - \0047b + \00474 - \0047c + \00475 - \0047d + \00476 - \0047e + \00477 - \0047f + \00478 - \00480 + \00479 - \00481 + \0047a - \00482 + \0047b - \00483 + \0047c - \00484 + \0047d - \00485 + \0047e - \00486 + \0047f - \00487 + \00480 - \00488 + \00481 - \00489 + \00482 - \0048a + \00483 - \0048b + \00484 - \0048c + \00485 - \0048d + \00486 - \0048e + \00487 - \0048f + \00488 - \00490 + \00489 - \00491 + \0048a - \00492 + \0048b - \00493 + \0048c - \00494 + \0048d - \00495 + \0048e - \00496 + \0048f - \00497 + \00490 - \00498 + \00491 - \00499 + \00492 - \0049a + \00493 - \0049b + \00494 - \0049c + \00495 - \0049d + \00496 - \0049e + \00497 - \0049f + \00498 - \004a0 + \00499 - \004a1 + \0049a - \004a2 + \0049b - \004a3 + \0049c - \004a4 + \0049d - \004a5 + \0049e - \004a6 + \0049f - \004a7 + \004a0 - \004a8 + \004a1 - \004a9 + \004a2 - \004aa + \004a3 - \004ab + \004a4 - \004ac + \004a5 - \004ad + \004a6 - \004ae + \004a7 - \004af + \004a8 - \004b0 + \004a9 - \004b1 + \004aa - \004b2 + \004ab - \004b3 + \004ac - \004b4 + \004ad - \004b5 + \004ae - \004b6 + \004af - \004b7 + \004b0 - \004b8 + \004b1 - \004b9 + \004b2 - \004ba + \004b3 - \004bb + \004b4 - \004bc + \004b5 - \004bd + \004b6 - \004be + \004b7 - \004bf + \004b8 - \004c0 + \004b9 - \004c1 + \004ba - \004c2 + \004bb - \004c3 + \004bc - \004c4 + \004bd - \004c5 + \004be - \004c6 + \004bf - \004c7 + \004c0 - \004c8 + \004c1 - \004c9 + \004c2 - \004ca + \004c3 - \004cb + \004c4 - \004cc + \004c5 - \004cd + \004c6 - \004ce + \004c7 - \004cf + \004c8 - \004d0 + \004c9 - \004d1 + \004ca - \004d2 + \004cb - \004d3 + \004cc - \004d4 + \004cd - \004d5 + \004ce - \004d6 + \004cf - \004d7 + \004d0 - \004d8 + \004d1 - \004d9 + \004d2 - \004da + \004d3 - \004db + \004d4 - \004dc + \004d5 - \004dd + \004d6 - \004de + \004d7 - \004df + \004d8 - \004e0 + \004d9 - \004e1 + \004da - \004e2 + \004db - \004e3 + \004dc - \004e4 + \004dd - \004e5 + \004de - \004e6 + \004df - \004e7 + \004e0 - \004e8 + \004e1 - \004e9 + \004e2 - \004ea + \004e3 - \004eb + \004e4 - \004ec + \004e5 - \004ed + \004e6 - \004ee + \004e7 - \004ef + \004e8 - \004f0 + \004e9 - \004f1 + \004ea - \004f2 + \004eb - \004f3 + \004ec - \004f4 + \004ed - \004f5 + \004ee - \004f6 + \004ef - \004f7 + \004f0 - \004f8 + \004f1 - \004f9 + \004f2 - \004fa + \004f3 - \004fb + \004f4 - \004fc + \004f5 - \004fd + \004f6 - \004fe + \004f7 - \004ff + \004f8 - \00500 + \004f9 - \00501 + \004fa - \00502 + \004fb - \00503 + \004fc - \00504 + \004fd - \00505 + \004fe - \00506 + \004ff - \00507 + \00500 - \00508 + \00501 - \00509 + \00502 - \0050a + \00503 - \0050b + \00504 - \0050c + \00505 - \0050d + \00506 - \0050e + \00507 - \0050f + \00508 - \00510 + \00509 - \00511 + \0050a - \00512 + \0050b - \00513 + \0050c - \00514 + \0050d - \00515 + \0050e - \00516 + \0050f - \00517 + \00510 - \00518 + \00511 - \00519 + \00512 - \0051a + \00513 - \0051b + \00514 - \0051c + \00515 - \0051d + \00516 - \0051e + \00517 - \0051f + \00518 - \00520 + \00519 - \00521 + \0051a - \00522 + \0051b - \00523 + \0051c - \00524 + \0051d - \00525 + \0051e - \00526 + \0051f - \00527 + \00520 - \00528 + \00521 - \00529 + \00522 - \0052a + \00523 - \0052b + \00524 - \0052c + \00525 - \0052d + \00526 - \0052e + \00527 - \0052f + \00528 - \00530 + \00529 - \00531 + \0052a - \00532 + \0052b - \00533 + \0052c - \00534 + \0052d - \00535 + \0052e - \00536 + \0052f - \00537 + \00530 - \00538 + \00531 - \00539 + \00532 - \0053a + \00533 - \0053b + \00534 - \0053c + \00535 - \0053d + \00536 - \0053e + \00537 - \0053f + \00538 - \00540 + \00539 - \00541 + \0053a - \00542 + \0053b - \00543 + \0053c - \00544 + \0053d - \00545 + \0053e - \00546 + \0053f - \00547 + \00540 - \00548 + \00541 - \00549 + \00542 - \0054a + \00543 - \0054b + \00544 - \0054c + \00545 - \0054d + \00546 - \0054e + \00547 - \0054f + \00548 - \00550 + \00549 - \00551 + \0054a - \00552 + \0054b - \00553 + \0054c - \00554 + \0054d - \00555 + \0054e - \00556 + \0054f - \00557 + \00550 - \00558 + \00551 - \00559 + \00552 - \0055a + \00553 - \0055b + \00554 - \0055c + \00555 - \0055d + \00556 - \0055e + \00557 - \0055f + \00558 - \00560 + \00559 - \00561 + \0055a - \00562 + \0055b - \00563 + \0055c - \00564 + \0055d - \00565 + \0055e - \00566 + \0055f - \00567 + \00560 - \00568 + \00561 - \00569 + \00562 - \0056a + \00563 - \0056b + \00564 - \0056c + \00565 - \0056d + \00566 - \0056e + \00567 - \0056f + \00568 - \00570 + \00569 - \00571 + \0056a - \00572 + \0056b - \00573 + \0056c - \00574 + \0056d - \00575 + \0056e - \00576 + \0056f - \00577 + \00570 - \00578 + \00571 - \00579 + \00572 - \0057a + \00573 - \0057b + \00574 - \0057c + \00575 - \0057d + \00576 - \0057e + \00577 - \0057f + \00578 - \00580 + \00579 - \00581 + \0057a - \00582 + \0057b - \00583 + \0057c - \00584 + \0057d - \00585 + \0057e - \00586 + \0057f - \00587 + \00580 - \00588 + \00581 - \00589 + \00582 - \0058a + \00583 - \0058b + \00584 - \0058c + \00585 - \0058d + \00586 - \0058e + \00587 - \0058f + \00588 - \00590 + \00589 - \00591 + \0058a - \00592 + \0058b - \00593 + \0058c - \00594 + \0058d - \00595 + \0058e - \00596 + \0058f - \00597 + \00590 - \00598 + \00591 - \00599 + \00592 - \0059a + \00593 - \0059b + \00594 - \0059c + \00595 - \0059d + \00596 - \0059e + \00597 - \0059f + \00598 - \005a0 + \00599 - \005a1 + \0059a - \005a2 + \0059b - \005a3 + \0059c - \005a4 + \0059d - \005a5 + \0059e - \005a6 + \0059f - \005a7 + \005a0 - \005a8 + \005a1 - \005a9 + \005a2 - \005aa + \005a3 - \005ab + \005a4 - \005ac + \005a5 - \005ad + \005a6 - \005ae + \005a7 - \005af + \005a8 - \005b0 + \005a9 - \005b1 + \005aa - \005b2 + \005ab - \005b3 + \005ac - \005b4 + \005ad - \005b5 + \005ae - \005b6 + \005af - \005b7 + \005b0 - \005b8 + \005b1 - \005b9 + \005b2 - \005ba + \005b3 - \005bb + \005b4 - \005bc + \005b5 - \005bd + \005b6 - \005be + \005b7 - \005bf + \005b8 - \005c0 + \005b9 - \005c1 + \005ba - \005c2 + \005bb - \005c3 + \005bc - \005c4 + \005bd - \005c5 + \005be - \005c6 + \005bf - \005c7 + \005c0 - \005c8 + \005c1 - \005c9 + \005c2 - \005ca + \005c3 - \005cb + \005c4 - \005cc + \005c5 - \005cd + \005c6 - \005ce + \005c7 - \005cf + \005c8 - \005d0 + \005c9 - \005d1 + \005ca - \005d2 + \005cb - \005d3 + \005cc - \005d4 + \005cd - \005d5 + \005ce - \005d6 + \005cf - \005d7 + \005d0 - \005d8 + \005d1 - \005d9 + \005d2 - \005da + \005d3 - \005db + \005d4 - \005dc + \005d5 - \005dd + \005d6 - \005de + \005d7 - \005df + \005d8 - \005e0 + \005d9 - \005e1 + \005da - \005e2 + \005db - \005e3 + \005dc - \005e4 + \005dd - \005e5 + \005de - \005e6 + \005df - \005e7 + \005e0 - \005e8 + \005e1 - \005e9 + \005e2 - \005ea + \005e3 - \005eb + \005e4 - \005ec + \005e5 - \005ed + \005e6 - \005ee + \005e7 - \005ef + \005e8 - \005f0 + \005e9 - \005f1 + \005ea - \005f2 + \005eb - \005f3 + \005ec - \005f4 + \005ed - \005f5 + \005ee - \005f6 + \005ef - \005f7 + \005f0 - \005f8 + \005f1 - \005f9 + \005f2 - \005fa + \005f3 - \005fb + \005f4 - \005fc + \005f5 - \005fd + \005f6 - \005fe + \005f7 - \005ff + \005f8 - \00600 + \005f9 - \00601 + \005fa - \00602 + \005fb - \00603 + \005fc - \00604 + \005fd - \00605 + \005fe - \00606 + \005ff - \00607 + \00600 - \00608 + \00601 - \00609 + \00602 - \0060a + \00603 - \0060b + \00604 - \0060c + \00605 - \0060d + \00606 - \0060e + \00607 - \0060f + \00608 - \00610 + \00609 - \00611 + \0060a - \00612 + \0060b - \00613 + \0060c - \00614 + \0060d - \00615 + \0060e - \00616 + \0060f - \00617 + \00610 - \00618 + \00611 - \00619 + \00612 - \0061a + \00613 - \0061b + \00614 - \0061c + \00615 - \0061d + \00616 - \0061e + \00617 - \0061f + \00618 - \00620 + \00619 - \00621 + \0061a - \00622 + \0061b - \00623 + \0061c - \00624 + \0061d - \00625 + \0061e - \00626 + \0061f - \00627 + \00620 - \00628 + \00621 - \00629 + \00622 - \0062a + \00623 - \0062b + \00624 - \0062c + \00625 - \0062d + \00626 - \0062e + \00627 - \0062f + \00628 - \00630 + \00629 - \00631 + \0062a - \00632 + \0062b - \00633 + \0062c - \00634 + \0062d - \00635 + \0062e - \00636 + \0062f - \00637 + \00630 - \00638 + \00631 - \00639 + \00632 - \0063a + \00633 - \0063b + \00634 - \0063c + \00635 - \0063d + \00636 - \0063e + \00637 - \0063f + \00638 - \00640 + \00639 - \00641 + \0063a - \00642 + \0063b - \00643 + \0063c - \00644 + \0063d - \00645 + \0063e - \00646 + \0063f - \00647 + \00640 - \00648 + \00641 - \00649 + I-465 Ramp - \0064a + \00642 - \0064b + \00643 - \0064c + \00644 - \0064d + \00645 - \0064e + I-465 - \0064f + \00646 - \00650 + \00647 - \00651 + \00648 - \00652 + \00649 - \00653 + \0064a - \00654 + \0064b - \00655 + \0064c - \00656 + \0064d - \00657 + \0064e - \00658 + \0064f - \00659 + \00650 - \0065a + \00651 - \0065b + \00652 - \0065c + \00653 - \0065d + \00654 - \0065e + \00655 - \0065f + \00656 - \00660 + \00657 - \00661 + \00658 - \00662 + \00659 - \00663 + \0065a - \00664 + \0065b - \00665 + \0065c - \00666 + \0065d - \00667 + \0065e - \00668 + \0065f - \00669 + \00660 - \0066a + \00661 - \0066b + \00662 - \0066c + \00663 - \0066d + 86th St W Ramp - \0066e + \00664 - \0066f + \00665 - \00670 + 86th St W - \00671 + \00666 - \00672 + \00667 - \00673 + Northwest Blvd - \00674 + \00668 diff --git a/reference/track/ignrando-sample.gpx b/reference/track/ignrando-sample.gpx new file mode 100644 index 000000000..298cdda3a --- /dev/null +++ b/reference/track/ignrando-sample.gpx @@ -0,0 +1,45 @@ + + + + + + 20050719 Mar Tamié ind 2 VTT Sem Europ + + + 331.000000 + + + 331.000000 + + + 333.000000 + + + 333.000000 + + + 333.000000 + + + 333.000000 + + + 333.000000 + + + 333.351990 + + + 334.760010 + + + 338.000000 + + + + diff --git a/reference/track/ignrando-sample.rdn b/reference/track/ignrando-sample.rdn new file mode 100644 index 000000000..93b40fd6f --- /dev/null +++ b/reference/track/ignrando-sample.rdn @@ -0,0 +1,76 @@ + + + + 1.1 + IFS0201 + 22/01/2005 + 13:45:56 + + + 10 + VTT + 30555.326809 + 13743.150894 + 1215.172668 + 1215.172668 + 0 + 0 + 20050719 Mar Tamié ind 2 VTT Sem Europ + 45.689877,6.300834,45.660805,6.394279 + 65280 + 5 + 0 + 65280 + 1 + 0 + + VTT rando + 2000.000000 + 15.000000 + 300.000000 + 0 + + 27054.002550 + 0 + + + 45.664261,6.372394 + 331.000000 + + + 45.664452,6.372383 + 331.000000 + + + 45.666973,6.371411 + 333.000000 + + + 45.667198,6.371414 + 333.000000 + + + 45.667271,6.371150 + 333.000000 + + + 45.667030,6.371043 + 333.000000 + + + 45.666859,6.370786 + 333.000000 + + + 45.660805,6.367349 + 333.351990 + + + 45.661282,6.366768 + 334.760010 + + + 45.662376,6.365717 + 338.000000 + + diff --git a/reference/track/interptrack.gpx b/reference/track/interptrack.gpx new file mode 100644 index 000000000..9fe10f4de --- /dev/null +++ b/reference/track/interptrack.gpx @@ -0,0 +1,154 @@ + + + + + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/kartex-out.ktf b/reference/track/kartex-out.ktf new file mode 100644 index 000000000..41e3b9d21 --- /dev/null +++ b/reference/track/kartex-out.ktf @@ -0,0 +1,179 @@ +//Kartex Track File created by GPSBabel +&KTF 2.0,sweref 99 lat long,0 +%,0,N56.151633° E13.760700°,54.00,2006-03-07 15:58:36,,,$ +%,1,N56.151683° E13.760700°,47.00,2006-03-07 15:58:38,,,$ +%,2,N56.151333° E13.760500°,47.00,2006-03-07 15:59:00,,,$ +%,3,N56.150933° E13.760317°,46.00,2006-03-07 15:59:29,,,$ +%,4,N56.150350° E13.759967°,46.00,2006-03-07 16:00:12,,,$ +%,5,N56.149733° E13.759650°,47.00,2006-03-07 16:00:58,,,$ +%,6,N56.149217° E13.759350°,48.00,2006-03-07 16:01:38,,,$ +%,7,N56.148833° E13.759117°,47.00,2006-03-07 16:02:06,,,$ +%,8,N56.148550° E13.759050°,47.00,2006-03-07 16:02:27,,,$ +%,9,N56.148033° E13.758850°,46.00,2006-03-07 16:03:04,,,$ +%,10,N56.147600° E13.758817°,46.00,2006-03-07 16:03:35,,,$ +%,11,N56.147300° E13.758767°,44.00,2006-03-07 16:04:02,,,$ +%,12,N56.147300° E13.758767°,45.00,2006-03-07 16:04:11,,,$ +%,13,N56.147283° E13.758633°,45.00,2006-03-07 16:04:16,,,$ +%,14,N56.147117° E13.758167°,46.00,2006-03-07 16:04:39,,,$ +%,15,N56.147000° E13.757750°,48.00,2006-03-07 16:04:59,,,$ +%,16,N56.146617° E13.757400°,47.00,2006-03-07 16:05:33,,,$ +%,17,N56.146217° E13.757183°,45.00,2006-03-07 16:06:04,,,$ +%,18,N56.145700° E13.756900°,43.00,2006-03-07 16:06:46,,,$ +%,19,N56.145450° E13.756900°,45.00,2006-03-07 16:07:07,,,$ +%,20,N56.145350° E13.757283°,45.00,2006-03-07 16:07:26,,,$ +%,21,N56.145300° E13.757450°,44.00,2006-03-07 16:07:35,,,$ +%,22,N56.144950° E13.757517°,45.00,2006-03-07 16:08:03,,,$ +%,23,N56.144667° E13.757800°,44.00,2006-03-07 16:08:28,,,$ +%,24,N56.144450° E13.758667°,41.00,2006-03-07 16:09:08,,,$ +%,25,N56.144517° E13.759000°,42.00,2006-03-07 16:09:23,,,$ +%,26,N56.144450° E13.759217°,43.00,2006-03-07 16:09:35,,,$ +%,27,N56.144133° E13.759150°,44.00,2006-03-07 16:09:58,,,$ +%,28,N56.143533° E13.759017°,45.00,2006-03-07 16:10:40,,,$ +%,29,N56.143117° E13.758550°,46.00,2006-03-07 16:11:14,,,$ +%,30,N56.142750° E13.758017°,48.00,2006-03-07 16:11:49,,,$ +%,31,N56.142183° E13.757550°,48.00,2006-03-07 16:12:34,,,$ +%,32,N56.142150° E13.757550°,48.00,2006-03-07 16:12:53,,,$ +%,33,N56.142133° E13.757500°,48.00,2006-03-07 16:13:21,,,$ +%,34,N56.141750° E13.757267°,50.00,2006-03-07 16:13:51,,,$ +%,35,N56.141450° E13.757117°,49.00,2006-03-07 16:14:17,,,$ +%,36,N56.141033° E13.756750°,46.00,2006-03-07 16:14:51,,,$ +%,37,N56.140733° E13.756350°,46.00,2006-03-07 16:15:19,,,$ +%,38,N56.140467° E13.756017°,46.00,2006-03-07 16:15:54,,,$ +%,39,N56.140400° E13.755933°,45.00,2006-03-07 16:16:13,,,$ +%,40,N56.140217° E13.755683°,44.00,2006-03-07 16:16:33,,,$ +%,41,N56.139750° E13.755200°,43.00,2006-03-07 16:17:11,,,$ +%,42,N56.139550° E13.754867°,44.00,2006-03-07 16:17:35,,,$ +%,43,N56.139500° E13.754800°,44.00,2006-03-07 16:17:41,,,$ +%,44,N56.139000° E13.755117°,43.00,2006-03-07 16:18:19,,,$ +%,45,N56.138767° E13.755167°,43.00,2006-03-07 16:18:35,,,$ +%,46,N56.138717° E13.755050°,44.00,2006-03-07 16:18:41,,,$ +%,47,N56.138617° E13.753750°,43.00,2006-03-07 16:19:36,,,$ +%,48,N56.138567° E13.753150°,44.00,2006-03-07 16:20:01,,,$ +%,49,N56.138333° E13.752767°,44.00,2006-03-07 16:20:25,,,$ +%,50,N56.137733° E13.752717°,44.00,2006-03-07 16:21:11,,,$ +%,51,N56.137067° E13.753167°,42.00,2006-03-07 16:22:05,,,$ +%,52,N56.136833° E13.753667°,43.00,2006-03-07 16:22:34,,,$ +%,53,N56.136633° E13.754150°,44.00,2006-03-07 16:23:01,,,$ +%,54,N56.136367° E13.754967°,44.00,2006-03-07 16:23:42,,,$ +%,55,N56.136300° E13.755183°,44.00,2006-03-07 16:24:03,,,$ +%,56,N56.136300° E13.755233°,44.00,2006-03-07 16:24:05,,,$ +%,57,N56.136217° E13.755283°,44.00,2006-03-07 16:24:11,,,$ +%,58,N56.135767° E13.754967°,44.00,2006-03-07 16:24:48,,,$ +%,59,N56.135350° E13.754650°,43.00,2006-03-07 16:25:22,,,$ +%,60,N56.134950° E13.754267°,44.00,2006-03-07 16:26:03,,,$ +%,61,N56.134767° E13.754067°,45.00,2006-03-07 16:26:35,,,$ +%,62,N56.134667° E13.753917°,44.00,2006-03-07 16:26:55,,,$ +%,63,N56.134167° E13.753183°,44.00,2006-03-07 16:27:42,,,$ +%,64,N56.133750° E13.752350°,44.00,2006-03-07 16:28:30,,,$ +%,65,N56.133700° E13.752250°,47.00,2006-03-07 16:28:55,,,$ +%,66,N56.133567° E13.751950°,48.00,2006-03-07 16:29:40,,,$ +%,67,N56.133250° E13.751100°,47.00,2006-03-07 16:30:23,,,$ +%,68,N56.132933° E13.750317°,47.00,2006-03-07 16:31:04,,,$ +%,69,N56.132633° E13.749517°,46.00,2006-03-07 16:31:45,,,$ +%,70,N56.132533° E13.748967°,43.00,2006-03-07 16:32:13,,,$ +%,71,N56.132500° E13.748850°,43.00,2006-03-07 16:32:27,,,$ +%,72,N56.132500° E13.748833°,43.00,2006-03-07 16:32:29,,,$ +%,73,N56.132050° E13.748367°,44.00,2006-03-07 16:33:09,,,$ +%,74,N56.131883° E13.748250°,45.00,2006-03-07 16:33:31,,,$ +%,75,N56.131367° E13.747767°,46.00,2006-03-07 16:34:15,,,$ +%,76,N56.131100° E13.747500°,47.00,2006-03-07 16:34:44,,,$ +%,77,N56.130667° E13.746983°,44.00,2006-03-07 16:35:22,,,$ +%,78,N56.130167° E13.746383°,43.00,2006-03-07 16:36:09,,,$ +%,79,N56.129683° E13.745833°,43.00,2006-03-07 16:36:52,,,$ +%,80,N56.129233° E13.745333°,44.00,2006-03-07 16:37:30,,,$ +%,81,N56.128717° E13.744783°,43.00,2006-03-07 16:38:15,,,$ +%,82,N56.128117° E13.744117°,43.00,2006-03-07 16:39:06,,,$ +%,83,N56.127600° E13.743550°,44.00,2006-03-07 16:39:52,,,$ +%,84,N56.127267° E13.743183°,44.00,2006-03-07 16:40:24,,,$ +%,85,N56.126783° E13.742767°,44.00,2006-03-07 16:41:05,,,$ +%,86,N56.126467° E13.742500°,44.00,2006-03-07 16:41:34,,,$ +%,87,N56.126233° E13.742317°,47.00,2006-03-07 16:42:03,,,$ +%,88,N56.126117° E13.742250°,46.00,2006-03-07 16:42:15,,,$ +%,89,N56.126083° E13.742200°,46.00,2006-03-07 16:42:37,,,$ +%,90,N56.125967° E13.742117°,46.00,2006-03-07 16:42:58,,,$ +%,91,N56.125783° E13.741983°,46.00,2006-03-07 16:43:16,,,$ +%,92,N56.125283° E13.741733°,47.00,2006-03-07 16:43:54,,,$ +%,93,N56.124767° E13.741467°,46.00,2006-03-07 16:44:36,,,$ +%,94,N56.124433° E13.741283°,44.00,2006-03-07 16:45:04,,,$ +%,95,N56.124000° E13.741000°,44.00,2006-03-07 16:45:38,,,$ +%,96,N56.123483° E13.740717°,44.00,2006-03-07 16:46:20,,,$ +%,97,N56.122933° E13.740550°,46.00,2006-03-07 16:47:02,,,$ +%,98,N56.122417° E13.740450°,49.00,2006-03-07 16:47:40,,,$ +%,99,N56.121817° E13.740283°,50.00,2006-03-07 16:48:25,,,$ +%,100,N56.121250° E13.740083°,51.00,2006-03-07 16:49:07,,,$ +%,101,N56.121133° E13.739983°,51.00,2006-03-07 16:49:31,,,$ +%,102,N56.121033° E13.739950°,52.00,2006-03-07 16:49:52,,,$ +%,103,N56.120983° E13.739950°,52.00,2006-03-07 16:50:18,,,$ +%,104,N56.120617° E13.739783°,52.00,2006-03-07 16:50:49,,,$ +%,105,N56.120267° E13.739600°,52.00,2006-03-07 16:51:23,,,$ +%,106,N56.120067° E13.739583°,53.00,2006-03-07 16:51:56,,,$ +%,107,N56.119800° E13.739500°,53.00,2006-03-07 16:52:26,,,$ +%,108,N56.119800° E13.739500°,52.00,2006-03-07 16:52:35,,,$ +%,109,N56.119233° E13.739567°,52.00,2006-03-07 16:53:17,,,$ +%,110,N56.118650° E13.739667°,51.00,2006-03-07 16:54:00,,,$ +%,111,N56.118050° E13.740033°,51.00,2006-03-07 16:54:47,,,$ +%,112,N56.117600° E13.740383°,50.00,2006-03-07 16:55:24,,,$ +%,113,N56.117067° E13.740550°,49.00,2006-03-07 16:56:05,,,$ +%,114,N56.116383° E13.740600°,50.00,2006-03-07 16:56:54,,,$ +%,115,N56.115950° E13.740617°,52.00,2006-03-07 16:57:27,,,$ +%,116,N56.115367° E13.740633°,52.00,2006-03-07 16:58:11,,,$ +%,117,N56.115033° E13.739867°,48.00,2006-03-07 16:58:52,,,$ +%,118,N56.114967° E13.739000°,46.00,2006-03-07 16:59:27,,,$ +%,119,N56.115017° E13.738233°,47.00,2006-03-07 16:59:57,,,$ +%,120,N56.115067° E13.737550°,46.00,2006-03-07 17:00:26,,,$ +%,121,N56.115367° E13.736733°,45.00,2006-03-07 17:01:07,,,$ +%,122,N56.115833° E13.736367°,44.00,2006-03-07 17:01:45,,,$ +%,123,N56.116317° E13.736017°,45.00,2006-03-07 17:02:25,,,$ +%,124,N56.116633° E13.735867°,44.00,2006-03-07 17:02:50,,,$ +%,125,N56.117217° E13.735650°,44.00,2006-03-07 17:03:32,,,$ +%,126,N56.117817° E13.735567°,45.00,2006-03-07 17:04:17,,,$ +%,127,N56.118400° E13.735417°,45.00,2006-03-07 17:04:59,,,$ +%,128,N56.118533° E13.735200°,45.00,2006-03-07 17:05:11,,,$ +%,129,N56.118933° E13.735167°,44.00,2006-03-07 17:05:43,,,$ +%,130,N56.119150° E13.735117°,44.00,2006-03-07 17:05:58,,,$ +%,131,N56.119267° E13.734750°,44.00,2006-03-07 17:06:16,,,$ +%,132,N56.119583° E13.734867°,44.00,2006-03-07 17:06:41,,,$ +%,133,N56.119833° E13.734333°,43.00,2006-03-07 17:07:15,,,$ +%,134,N56.120067° E13.734033°,43.00,2006-03-07 17:07:38,,,$ +%,135,N56.120283° E13.733883°,43.00,2006-03-07 17:07:59,,,$ +%,136,N56.120350° E13.733850°,43.00,2006-03-07 17:08:27,,,$ +%,137,N56.120350° E13.733850°,43.00,2006-03-07 17:08:35,,,$ +%,138,N56.120667° E13.733267°,41.00,2006-03-07 17:09:12,,,$ +%,139,N56.120933° E13.732717°,41.00,2006-03-07 17:09:45,,,$ +%,140,N56.121167° E13.732217°,40.00,2006-03-07 17:10:14,,,$ +%,141,N56.121450° E13.731583°,40.00,2006-03-07 17:10:51,,,$ +%,142,N56.121783° E13.730833°,41.00,2006-03-07 17:11:35,,,$ +%,143,N56.122033° E13.730100°,41.00,2006-03-07 17:12:14,,,$ +%,144,N56.122283° E13.729500°,40.00,2006-03-07 17:12:47,,,$ +%,145,N56.122583° E13.728817°,39.00,2006-03-07 17:13:27,,,$ +%,146,N56.122883° E13.728083°,40.00,2006-03-07 17:14:09,,,$ +%,147,N56.123167° E13.727433°,41.00,2006-03-07 17:14:48,,,$ +%,148,N56.123267° E13.727200°,41.00,2006-03-07 17:15:08,,,$ +%,149,N56.123450° E13.726867°,41.00,2006-03-07 17:15:32,,,$ +%,150,N56.123633° E13.726383°,40.00,2006-03-07 17:15:59,,,$ +%,151,N56.123900° E13.725867°,40.00,2006-03-07 17:16:30,,,$ +%,152,N56.124217° E13.725250°,39.00,2006-03-07 17:17:09,,,$ +%,153,N56.124467° E13.724750°,40.00,2006-03-07 17:17:41,,,$ +%,154,N56.124733° E13.724117°,39.00,2006-03-07 17:18:17,,,$ +%,155,N56.124833° E13.723750°,38.00,2006-03-07 17:18:45,,,$ +%,156,N56.124950° E13.723450°,38.00,2006-03-07 17:19:21,,,$ +%,157,N56.125200° E13.722850°,38.00,2006-03-07 17:19:54,,,$ +%,158,N56.125333° E13.722567°,38.00,2006-03-07 17:20:12,,,$ +%,159,N56.125400° E13.722317°,38.00,2006-03-07 17:20:29,,,$ +%,160,N56.125467° E13.722500°,39.00,2006-03-07 17:20:39,,,$ +%,161,N56.125783° E13.722650°,40.00,2006-03-07 17:21:06,,,$ +%,162,N56.125817° E13.722667°,40.00,2006-03-07 17:21:11,,,$ +%,163,N56.125883° E13.722650°,40.00,2006-03-07 17:21:16,,,$ +%,164,N56.125850° E13.722367°,41.00,2006-03-07 17:21:32,,,$ +%,165,N56.125867° E13.722133°,41.00,2006-03-07 17:21:56,,,$ +%,166,N56.125867° E13.722050°,42.00,2006-03-07 17:22:16,,,$ +%,167,N56.125850° E13.722050°,41.00,2006-03-07 17:22:52,,,$ +%,168,N56.125867° E13.721950°,41.00,2006-03-07 17:23:10,,,$ +%,169,N56.125917° E13.721967°,41.00,2006-03-07 17:23:30,,,$ +%,170,N56.125883° E13.721967°,41.00,2006-03-07 17:24:15,,,$ +%,171,N56.125867° E13.722167°,38.00,2006-03-07 17:33:44,,,$ +%,172,N56.125800° E13.722217°,38.00,2006-03-07 17:34:10,,,$ +%,173,N56.125783° E13.722250°,40.00,2006-03-07 17:34:40,,,$ +%,174,N56.125783° E13.722200°,40.00,2006-03-07 17:34:58,,,$ +%,175,N56.125817° E13.722317°,41.00,2006-03-07 17:35:12,,,$ +%,176,N56.125817° E13.722317°,40.00,2006-03-07 17:35:52,,,$ diff --git a/reference/track/kartex.txt b/reference/track/kartex.txt new file mode 100644 index 000000000..76d87bb6b --- /dev/null +++ b/reference/track/kartex.txt @@ -0,0 +1,182 @@ +Grid Lat/Lon hddd°mm.mmm' +Datum WGS 84 + +Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories + +Waypoint WPT001 User Waypoint N56 09.098 E13 45.642 54 m Symbol & Name Unknown Waypoint 07/03/2006 15:58:36 +Waypoint WPT002 User Waypoint N56 09.101 E13 45.642 47 m Symbol & Name Unknown Waypoint 07/03/2006 15:58:38 +Waypoint WPT003 User Waypoint N56 09.080 E13 45.630 47 m Symbol & Name Unknown Waypoint 07/03/2006 15:59:00 +Waypoint WPT004 User Waypoint N56 09.056 E13 45.619 46 m Symbol & Name Unknown Waypoint 07/03/2006 15:59:29 +Waypoint WPT005 User Waypoint N56 09.021 E13 45.598 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:00:12 +Waypoint WPT006 User Waypoint N56 08.984 E13 45.579 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:00:58 +Waypoint WPT007 User Waypoint N56 08.953 E13 45.561 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:01:38 +Waypoint WPT008 User Waypoint N56 08.930 E13 45.547 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:02:06 +Waypoint WPT009 User Waypoint N56 08.913 E13 45.543 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:02:27 +Waypoint WPT010 User Waypoint N56 08.882 E13 45.531 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:03:04 +Waypoint WPT011 User Waypoint N56 08.856 E13 45.529 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:03:35 +Waypoint WPT012 User Waypoint N56 08.838 E13 45.526 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:02 +Waypoint WPT013 User Waypoint N56 08.838 E13 45.526 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:11 +Waypoint WPT014 User Waypoint N56 08.837 E13 45.518 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:16 +Waypoint WPT015 User Waypoint N56 08.827 E13 45.490 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:39 +Waypoint WPT016 User Waypoint N56 08.820 E13 45.465 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:04:59 +Waypoint WPT017 User Waypoint N56 08.797 E13 45.444 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:05:33 +Waypoint WPT018 User Waypoint N56 08.773 E13 45.431 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:06:04 +Waypoint WPT019 User Waypoint N56 08.742 E13 45.414 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:06:46 +Waypoint WPT020 User Waypoint N56 08.727 E13 45.414 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:07:07 +Waypoint WPT021 User Waypoint N56 08.721 E13 45.437 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:07:26 +Waypoint WPT022 User Waypoint N56 08.718 E13 45.447 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:07:35 +Waypoint WPT023 User Waypoint N56 08.697 E13 45.451 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:08:03 +Waypoint WPT024 User Waypoint N56 08.680 E13 45.468 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:08:28 +Waypoint WPT025 User Waypoint N56 08.667 E13 45.520 41 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:08 +Waypoint WPT026 User Waypoint N56 08.671 E13 45.540 42 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:23 +Waypoint WPT027 User Waypoint N56 08.667 E13 45.553 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:35 +Waypoint WPT028 User Waypoint N56 08.648 E13 45.549 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:09:58 +Waypoint WPT029 User Waypoint N56 08.612 E13 45.541 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:10:40 +Waypoint WPT030 User Waypoint N56 08.587 E13 45.513 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:11:14 +Waypoint WPT031 User Waypoint N56 08.565 E13 45.481 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:11:49 +Waypoint WPT032 User Waypoint N56 08.531 E13 45.453 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:12:34 +Waypoint WPT033 User Waypoint N56 08.529 E13 45.453 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:12:53 +Waypoint WPT034 User Waypoint N56 08.528 E13 45.450 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:13:21 +Waypoint WPT035 User Waypoint N56 08.505 E13 45.436 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:13:51 +Waypoint WPT036 User Waypoint N56 08.487 E13 45.427 49 m Symbol & Name Unknown Waypoint 07/03/2006 16:14:17 +Waypoint WPT037 User Waypoint N56 08.462 E13 45.405 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:14:51 +Waypoint WPT038 User Waypoint N56 08.444 E13 45.381 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:15:19 +Waypoint WPT039 User Waypoint N56 08.428 E13 45.361 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:15:54 +Waypoint WPT040 User Waypoint N56 08.424 E13 45.356 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:16:13 +Waypoint WPT041 User Waypoint N56 08.413 E13 45.341 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:16:33 +Waypoint WPT042 User Waypoint N56 08.385 E13 45.312 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:17:11 +Waypoint WPT043 User Waypoint N56 08.373 E13 45.292 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:17:35 +Waypoint WPT044 User Waypoint N56 08.370 E13 45.288 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:17:41 +Waypoint WPT045 User Waypoint N56 08.340 E13 45.307 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:18:19 +Waypoint WPT046 User Waypoint N56 08.326 E13 45.310 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:18:35 +Waypoint WPT047 User Waypoint N56 08.323 E13 45.303 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:18:41 +Waypoint WPT048 User Waypoint N56 08.317 E13 45.225 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:19:36 +Waypoint WPT049 User Waypoint N56 08.314 E13 45.189 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:20:01 +Waypoint WPT050 User Waypoint N56 08.300 E13 45.166 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:20:25 +Waypoint WPT051 User Waypoint N56 08.264 E13 45.163 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:21:11 +Waypoint WPT052 User Waypoint N56 08.224 E13 45.190 42 m Symbol & Name Unknown Waypoint 07/03/2006 16:22:05 +Waypoint WPT053 User Waypoint N56 08.210 E13 45.220 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:22:34 +Waypoint WPT054 User Waypoint N56 08.198 E13 45.249 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:23:01 +Waypoint WPT055 User Waypoint N56 08.182 E13 45.298 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:23:42 +Waypoint WPT056 User Waypoint N56 08.178 E13 45.311 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:03 +Waypoint WPT057 User Waypoint N56 08.178 E13 45.314 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:05 +Waypoint WPT058 User Waypoint N56 08.173 E13 45.317 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:11 +Waypoint WPT059 User Waypoint N56 08.146 E13 45.298 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:24:48 +Waypoint WPT060 User Waypoint N56 08.121 E13 45.279 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:25:22 +Waypoint WPT061 User Waypoint N56 08.097 E13 45.256 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:26:03 +Waypoint WPT062 User Waypoint N56 08.086 E13 45.244 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:26:35 +Waypoint WPT063 User Waypoint N56 08.080 E13 45.235 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:26:55 +Waypoint WPT064 User Waypoint N56 08.050 E13 45.191 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:27:42 +Waypoint WPT065 User Waypoint N56 08.025 E13 45.141 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:28:30 +Waypoint WPT066 User Waypoint N56 08.022 E13 45.135 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:28:55 +Waypoint WPT067 User Waypoint N56 08.014 E13 45.117 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:29:40 +Waypoint WPT068 User Waypoint N56 07.995 E13 45.066 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:30:23 +Waypoint WPT069 User Waypoint N56 07.976 E13 45.019 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:31:04 +Waypoint WPT070 User Waypoint N56 07.958 E13 44.971 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:31:45 +Waypoint WPT071 User Waypoint N56 07.952 E13 44.938 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:32:13 +Waypoint WPT072 User Waypoint N56 07.950 E13 44.931 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:32:27 +Waypoint WPT073 User Waypoint N56 07.950 E13 44.930 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:32:29 +Waypoint WPT074 User Waypoint N56 07.923 E13 44.902 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:33:09 +Waypoint WPT075 User Waypoint N56 07.913 E13 44.895 45 m Symbol & Name Unknown Waypoint 07/03/2006 16:33:31 +Waypoint WPT076 User Waypoint N56 07.882 E13 44.866 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:34:15 +Waypoint WPT077 User Waypoint N56 07.866 E13 44.850 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:34:44 +Waypoint WPT078 User Waypoint N56 07.840 E13 44.819 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:35:22 +Waypoint WPT079 User Waypoint N56 07.810 E13 44.783 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:36:09 +Waypoint WPT080 User Waypoint N56 07.781 E13 44.750 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:36:52 +Waypoint WPT081 User Waypoint N56 07.754 E13 44.720 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:37:30 +Waypoint WPT082 User Waypoint N56 07.723 E13 44.687 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:38:15 +Waypoint WPT083 User Waypoint N56 07.687 E13 44.647 43 m Symbol & Name Unknown Waypoint 07/03/2006 16:39:06 +Waypoint WPT084 User Waypoint N56 07.656 E13 44.613 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:39:52 +Waypoint WPT085 User Waypoint N56 07.636 E13 44.591 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:40:24 +Waypoint WPT086 User Waypoint N56 07.607 E13 44.566 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:41:05 +Waypoint WPT087 User Waypoint N56 07.588 E13 44.550 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:41:34 +Waypoint WPT088 User Waypoint N56 07.574 E13 44.539 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:03 +Waypoint WPT089 User Waypoint N56 07.567 E13 44.535 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:15 +Waypoint WPT090 User Waypoint N56 07.565 E13 44.532 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:37 +Waypoint WPT091 User Waypoint N56 07.558 E13 44.527 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:42:58 +Waypoint WPT092 User Waypoint N56 07.547 E13 44.519 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:43:16 +Waypoint WPT093 User Waypoint N56 07.517 E13 44.504 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:43:54 +Waypoint WPT094 User Waypoint N56 07.486 E13 44.488 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:44:36 +Waypoint WPT095 User Waypoint N56 07.466 E13 44.477 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:45:04 +Waypoint WPT096 User Waypoint N56 07.440 E13 44.460 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:45:38 +Waypoint WPT097 User Waypoint N56 07.409 E13 44.443 44 m Symbol & Name Unknown Waypoint 07/03/2006 16:46:20 +Waypoint WPT098 User Waypoint N56 07.376 E13 44.433 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:47:02 +Waypoint WPT099 User Waypoint N56 07.345 E13 44.427 49 m Symbol & Name Unknown Waypoint 07/03/2006 16:47:40 +Waypoint WPT100 User Waypoint N56 07.309 E13 44.417 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:48:25 +Waypoint WPT101 User Waypoint N56 07.275 E13 44.405 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:49:07 +Waypoint WPT102 User Waypoint N56 07.268 E13 44.399 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:49:31 +Waypoint WPT103 User Waypoint N56 07.262 E13 44.397 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:49:52 +Waypoint WPT104 User Waypoint N56 07.259 E13 44.397 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:50:18 +Waypoint WPT105 User Waypoint N56 07.237 E13 44.387 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:50:49 +Waypoint WPT106 User Waypoint N56 07.216 E13 44.376 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:51:23 +Waypoint WPT107 User Waypoint N56 07.204 E13 44.375 53 m Symbol & Name Unknown Waypoint 07/03/2006 16:51:56 +Waypoint WPT108 User Waypoint N56 07.188 E13 44.370 53 m Symbol & Name Unknown Waypoint 07/03/2006 16:52:26 +Waypoint WPT109 User Waypoint N56 07.188 E13 44.370 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:52:35 +Waypoint WPT110 User Waypoint N56 07.154 E13 44.374 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:53:17 +Waypoint WPT111 User Waypoint N56 07.119 E13 44.380 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:54:00 +Waypoint WPT112 User Waypoint N56 07.083 E13 44.402 51 m Symbol & Name Unknown Waypoint 07/03/2006 16:54:47 +Waypoint WPT113 User Waypoint N56 07.056 E13 44.423 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:55:24 +Waypoint WPT114 User Waypoint N56 07.024 E13 44.433 49 m Symbol & Name Unknown Waypoint 07/03/2006 16:56:05 +Waypoint WPT115 User Waypoint N56 06.983 E13 44.436 50 m Symbol & Name Unknown Waypoint 07/03/2006 16:56:54 +Waypoint WPT116 User Waypoint N56 06.957 E13 44.437 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:57:27 +Waypoint WPT117 User Waypoint N56 06.922 E13 44.438 52 m Symbol & Name Unknown Waypoint 07/03/2006 16:58:11 +Waypoint WPT118 User Waypoint N56 06.902 E13 44.392 48 m Symbol & Name Unknown Waypoint 07/03/2006 16:58:52 +Waypoint WPT119 User Waypoint N56 06.898 E13 44.340 46 m Symbol & Name Unknown Waypoint 07/03/2006 16:59:27 +Waypoint WPT120 User Waypoint N56 06.901 E13 44.294 47 m Symbol & Name Unknown Waypoint 07/03/2006 16:59:57 +Waypoint WPT121 User Waypoint N56 06.904 E13 44.253 46 m Symbol & Name Unknown Waypoint 07/03/2006 17:00:26 +Waypoint WPT122 User Waypoint N56 06.922 E13 44.204 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:01:07 +Waypoint WPT123 User Waypoint N56 06.950 E13 44.182 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:01:45 +Waypoint WPT124 User Waypoint N56 06.979 E13 44.161 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:02:25 +Waypoint WPT125 User Waypoint N56 06.998 E13 44.152 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:02:50 +Waypoint WPT126 User Waypoint N56 07.033 E13 44.139 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:03:32 +Waypoint WPT127 User Waypoint N56 07.069 E13 44.134 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:04:17 +Waypoint WPT128 User Waypoint N56 07.104 E13 44.125 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:04:59 +Waypoint WPT129 User Waypoint N56 07.112 E13 44.112 45 m Symbol & Name Unknown Waypoint 07/03/2006 17:05:11 +Waypoint WPT130 User Waypoint N56 07.136 E13 44.110 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:05:43 +Waypoint WPT131 User Waypoint N56 07.149 E13 44.107 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:05:58 +Waypoint WPT132 User Waypoint N56 07.156 E13 44.085 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:06:16 +Waypoint WPT133 User Waypoint N56 07.175 E13 44.092 44 m Symbol & Name Unknown Waypoint 07/03/2006 17:06:41 +Waypoint WPT134 User Waypoint N56 07.190 E13 44.060 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:07:15 +Waypoint WPT135 User Waypoint N56 07.204 E13 44.042 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:07:38 +Waypoint WPT136 User Waypoint N56 07.217 E13 44.033 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:07:59 +Waypoint WPT137 User Waypoint N56 07.221 E13 44.031 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:08:27 +Waypoint WPT138 User Waypoint N56 07.221 E13 44.031 43 m Symbol & Name Unknown Waypoint 07/03/2006 17:08:35 +Waypoint WPT139 User Waypoint N56 07.240 E13 43.996 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:09:12 +Waypoint WPT140 User Waypoint N56 07.256 E13 43.963 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:09:45 +Waypoint WPT141 User Waypoint N56 07.270 E13 43.933 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:10:14 +Waypoint WPT142 User Waypoint N56 07.287 E13 43.895 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:10:51 +Waypoint WPT143 User Waypoint N56 07.307 E13 43.850 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:11:35 +Waypoint WPT144 User Waypoint N56 07.322 E13 43.806 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:12:14 +Waypoint WPT145 User Waypoint N56 07.337 E13 43.770 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:12:47 +Waypoint WPT146 User Waypoint N56 07.355 E13 43.729 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:13:27 +Waypoint WPT147 User Waypoint N56 07.373 E13 43.685 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:14:09 +Waypoint WPT148 User Waypoint N56 07.390 E13 43.646 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:14:48 +Waypoint WPT149 User Waypoint N56 07.396 E13 43.632 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:15:08 +Waypoint WPT150 User Waypoint N56 07.407 E13 43.612 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:15:32 +Waypoint WPT151 User Waypoint N56 07.418 E13 43.583 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:15:59 +Waypoint WPT152 User Waypoint N56 07.434 E13 43.552 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:16:30 +Waypoint WPT153 User Waypoint N56 07.453 E13 43.515 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:17:09 +Waypoint WPT154 User Waypoint N56 07.468 E13 43.485 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:17:41 +Waypoint WPT155 User Waypoint N56 07.484 E13 43.447 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:18:17 +Waypoint WPT156 User Waypoint N56 07.490 E13 43.425 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:18:45 +Waypoint WPT157 User Waypoint N56 07.497 E13 43.407 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:19:21 +Waypoint WPT158 User Waypoint N56 07.512 E13 43.371 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:19:54 +Waypoint WPT159 User Waypoint N56 07.520 E13 43.354 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:20:12 +Waypoint WPT160 User Waypoint N56 07.524 E13 43.339 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:20:29 +Waypoint WPT161 User Waypoint N56 07.528 E13 43.350 39 m Symbol & Name Unknown Waypoint 07/03/2006 17:20:39 +Waypoint WPT162 User Waypoint N56 07.547 E13 43.359 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:06 +Waypoint WPT163 User Waypoint N56 07.549 E13 43.360 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:11 +Waypoint WPT164 User Waypoint N56 07.553 E13 43.359 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:16 +Waypoint WPT165 User Waypoint N56 07.551 E13 43.342 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:32 +Waypoint WPT166 User Waypoint N56 07.552 E13 43.328 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:21:56 +Waypoint WPT167 User Waypoint N56 07.552 E13 43.323 42 m Symbol & Name Unknown Waypoint 07/03/2006 17:22:16 +Waypoint WPT168 User Waypoint N56 07.551 E13 43.323 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:22:52 +Waypoint WPT169 User Waypoint N56 07.552 E13 43.317 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:23:10 +Waypoint WPT170 User Waypoint N56 07.555 E13 43.318 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:23:30 +Waypoint WPT171 User Waypoint N56 07.553 E13 43.318 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:24:15 +Waypoint WPT172 User Waypoint N56 07.552 E13 43.330 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:33:44 +Waypoint WPT173 User Waypoint N56 07.548 E13 43.333 38 m Symbol & Name Unknown Waypoint 07/03/2006 17:34:10 +Waypoint WPT174 User Waypoint N56 07.547 E13 43.335 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:34:40 +Waypoint WPT175 User Waypoint N56 07.547 E13 43.332 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:34:58 +Waypoint WPT176 User Waypoint N56 07.549 E13 43.339 41 m Symbol & Name Unknown Waypoint 07/03/2006 17:35:12 +Waypoint WPT177 User Waypoint N56 07.549 E13 43.339 40 m Symbol & Name Unknown Waypoint 07/03/2006 17:35:52 diff --git a/reference/track/nmea.gpx b/reference/track/nmea.gpx new file mode 100644 index 000000000..dc02404fe --- /dev/null +++ b/reference/track/nmea.gpx @@ -0,0 +1,1708 @@ + + + + + + + + 209.800000 + + 138.919998 + 0.083333 + 3d + 5 + 1.600000 + 4.500000 + 4.900000 + + + 209.700000 + + 145.850006 + 0.083333 + 3d + 5 + 1.600000 + 4.500000 + 4.900000 + + + 209.700000 + + 143.250000 + 0.083333 + 3d + 5 + 1.600000 + 4.500000 + 4.900000 + + + 209.600000 + + 145.759995 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.600000 + + 141.440002 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.600000 + + 140.399994 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.600000 + + 142.509995 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.400000 + + 144.059998 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.300000 + + 137.660004 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.100000 + + 144.229996 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.900000 + + 140.350006 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.800000 + + 143.059998 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.600000 + + 145.080002 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.500000 + + 141.559998 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.400000 + + 140.759995 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.400000 + + 143.919998 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.300000 + + 140.850006 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.200000 + + 145.270004 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.000000 + + 145.610001 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.900000 + + 145.139999 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.800000 + + 143.490005 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.700000 + + 145.089996 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.800000 + + 143.000000 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 207.900000 + + 144.100006 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.200000 + + 142.360001 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 208.600000 + + 139.899994 + 0.083333 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.200000 + + 145.610001 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 209.800000 + + 143.770004 + 0.111111 + 3d + 5 + 1.600000 + 4.600000 + 4.900000 + + + 210.600000 + + 144.649994 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 211.400000 + + 144.570007 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.200000 + + 144.350006 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.900000 + + 141.220001 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.500000 + + 146.149994 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.900000 + + 142.419998 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.100000 + + 141.130005 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.100000 + + 144.000000 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.800000 + + 142.179993 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.400000 + + 145.289993 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.000000 + + 144.630005 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.600000 + + 143.470001 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.400000 + + 142.350006 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.200000 + + 143.190002 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.100000 + + 143.639999 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.100000 + + 140.800003 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.100000 + + 141.910004 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.200000 + + 142.309998 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.400000 + + 140.729996 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.600000 + + 141.190002 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 212.900000 + + 142.600006 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.400000 + + 142.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.800000 + + 140.440002 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.200000 + + 142.369995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.700000 + + 139.389999 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.000000 + + 139.869995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 141.369995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 139.160004 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 142.389999 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.200000 + + 140.449997 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 215.100000 + + 141.089996 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.800000 + + 140.729996 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.600000 + + 137.970001 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.300000 + + 144.869995 + 0.111111 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 214.000000 + + 137.610001 + 0.083333 + 3d + 6 + 1.600000 + 4.300000 + 4.700000 + + + 213.700000 + + 145.339996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.400000 + + 136.350006 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 138.580002 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 140.110001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 212.900000 + + 140.309998 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 212.900000 + + 138.899994 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 142.899994 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.100000 + + 143.660004 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.300000 + + 140.869995 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.300000 + + 146.139999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.300000 + + 141.570007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 143.949997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 141.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.100000 + + 142.070007 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 140.210007 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 145.889999 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.000000 + + 139.509995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.200000 + + 144.059998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.500000 + + 143.089996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 213.900000 + + 141.050003 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 214.300000 + + 143.820007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 214.800000 + + 143.529999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 215.100000 + + 144.089996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 215.600000 + + 142.949997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 216.100000 + + 142.279999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 216.700000 + + 141.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 217.300000 + + 142.059998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 218.000000 + + 141.460007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 218.800000 + + 141.259995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 219.700000 + + 145.539993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 220.600000 + + 134.630005 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 221.700000 + + 144.440002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 222.700000 + + 146.970001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.800000 + + 142.240005 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.800000 + + 142.729996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.700000 + + 141.520004 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.400000 + + 141.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.000000 + + 137.690002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.500000 + + 144.580002 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.900000 + + 144.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.200000 + + 143.139999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.300000 + + 143.270004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.400000 + + 139.119995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.300000 + + 140.070007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 228.100000 + + 144.720001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.800000 + + 140.800003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.500000 + + 143.259995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 227.200000 + + 138.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.800000 + + 143.110001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.400000 + + 140.100006 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 226.100000 + + 143.550003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.900000 + + 142.119995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.700000 + + 141.639999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.600000 + + 143.270004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.600000 + + 143.910004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.500000 + + 145.970001 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.400000 + + 144.000000 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 146.250000 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 138.979996 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.100000 + + 143.100006 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.900000 + + 140.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.700000 + + 141.440002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.500000 + + 142.979996 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 145.029999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 143.059998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 145.490005 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.500000 + + 141.300003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.700000 + + 141.190002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.000000 + + 143.009995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 140.809998 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 140.789993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 141.429993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.300000 + + 142.300003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 140.809998 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 142.399994 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.200000 + + 140.330002 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.100000 + + 137.770004 + 0.083333 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 225.000000 + + 142.289993 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.900000 + + 140.869995 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.700000 + + 141.699997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.500000 + + 141.699997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.300000 + + 140.330002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 224.100000 + + 139.050003 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.900000 + + 144.460007 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.700000 + + 139.029999 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.400000 + + 142.190002 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 223.100000 + + 141.350006 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 222.700000 + + 142.449997 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 222.300000 + + 142.000000 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 221.900000 + + 138.740005 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + 221.400000 + + 137.910004 + 0.111111 + 3d + 6 + 1.600000 + 4.400000 + 4.700000 + + + + diff --git a/reference/track/pathaway.gpx b/reference/track/pathaway.gpx index 72552ca80..8fac5b369 100644 --- a/reference/track/pathaway.gpx +++ b/reference/track/pathaway.gpx @@ -1,4 +1,4 @@ - + + 20050116_Fahrradtour Gerd - 344.774223 + 344.770031 - 344.774223 + 344.770031 - 344.774223 + 344.770031 - 344.774223 + 344.770031 - 345.735538 + 345.731334 - 345.735538 + 345.731334 - 371.210825 + 371.206311 - 374.094649 + 374.090100 - 379.382067 + 379.377454 - 381.304698 + 381.300061 - 381.785294 + 381.780652 - 381.785294 + 381.780652 - 382.746732 + 382.742078 - 384.669485 + 384.664807 - 385.630678 + 385.625989 - 386.111397 + 386.106702 - 386.592116 + 386.587415 - 386.111397 + 386.106702 - 384.188766 + 384.184094 - 377.459436 + 377.454846 - 375.056086 + 375.051526 - 375.056086 + 375.051526 - 375.056086 + 375.051526 - 375.056086 + 375.051526 - 373.133455 + 373.128918 - 372.172018 + 372.167492 - 368.807475 + 368.802990 - 362.078145 + 362.073742 - 360.636111 + 360.631725 - 357.271446 + 357.267101 - 355.348815 + 355.344494 - 354.387499 + 354.383190 - 351.503431 + 351.499157 - 349.580800 + 349.576549 - 346.696854 + 346.692638 - 346.216257 + 346.212047 - 343.812786 + 343.808605 - 338.044893 + 338.040782 - 337.083577 + 337.079479 - 336.122262 + 336.118175 - 336.122262 + 336.118175 - 337.564174 + 337.560069 - 334.680228 + 334.676158 - 338.044893 + 338.040782 - 337.564174 + 337.560069 - 337.564174 + 337.560069 - 338.525612 + 338.521495 - 339.486805 + 339.482677 - 347.177451 + 347.173229 - 347.658169 + 347.653942 - 347.177451 + 347.173229 - 346.696854 + 346.692638 - 347.658169 + 347.653942 - 347.658169 + 347.653942 - 347.177451 + 347.173229 - 349.100081 + 349.095836 - 349.580800 + 349.576549 - 350.061519 + 350.057262 - 351.984150 + 351.979870 - 366.884722 + 366.880261 - 368.807475 + 368.802990 - 372.172018 + 372.167492 - 373.614052 + 373.609509 - 376.498121 + 376.493542 - 377.459436 + 377.454846 - 378.420751 + 378.416150 - 383.707925 + 383.703259 - 388.034028 + 388.029309 - 388.514747 + 388.510022 - 390.917974 + 390.913221 - 394.763358 + 394.758558 - 390.917974 + 390.913221 - 386.592116 + 386.587415 - 386.592116 + 386.587415 - 390.917974 + 390.913221 - 391.398571 + 391.393811 - 401.973407 + 401.968519 - 414.470507 + 414.465467 - 419.757925 + 419.752821 - 419.277329 + 419.272230 - 421.199959 + 421.194838 - 425.525940 + 425.520766 - 426.006537 + 426.001356 - 427.448571 + 427.443373 - 430.332517 + 430.327284 - 435.619813 + 435.614516 - 436.581251 + 436.575942 - 437.542444 + 437.537123 - 438.503881 + 438.498549 - 441.868546 + 441.863173 - 445.233089 + 445.227675 - 446.675124 + 446.669692 - 441.387828 + 441.382460 - 440.426634 + 440.421279 - 438.984478 + 438.979140 - 437.061847 + 437.056533 - 433.216585 + 433.211318 - 433.216585 + 433.211318 - 433.697182 + 433.691908 - 437.542444 + 437.537123 - 453.404454 + 453.398940 - 449.078473 + 449.073012 - 446.675124 + 446.669692 - 446.675124 + 446.669692 - 445.233089 + 445.227675 - 440.907231 + 440.901870 - 435.139216 + 435.133925 - 433.216585 + 433.211318 - 433.216585 + 433.211318 - 432.735989 + 432.730727 - 432.735989 + 432.730727 - 432.735989 + 432.730727 - 431.293833 + 431.288588 - 430.813236 + 430.807997 - 423.603187 + 423.598036 - 415.431945 + 415.426893 - 417.354698 + 417.349623 - 424.564625 + 424.559462 - 422.161153 + 422.156019 - 411.105964 + 411.100965 - 413.509314 + 413.504286 - 420.238522 + 420.233412 - 428.890605 + 428.885390 - 435.139216 + 435.133925 - 437.542444 + 437.537123 - 447.155720 + 447.150283 - 459.653187 + 459.647598 - 470.708376 + 470.702652 - 478.399021 + 478.393204 - 474.553759 + 474.547989 - 487.531579 + 487.525650 - 505.316341 + 505.310197 - 511.564953 + 511.558732 - 521.658948 + 521.652605 - 528.868997 + 528.862566 - 527.907437 + 527.901018 - 521.658948 + 521.652605 - 526.946244 + 526.939836 - 540.404904 + 540.398333 - 550.979374 + 550.972674 - 557.708948 + 557.702166 - 569.244733 + 569.237811 - 569.725452 + 569.718524 - 555.305354 + 555.298602 - 543.769447 + 543.762835 - 531.272224 + 531.265764 - 516.371530 + 516.365251 - 511.084234 + 511.078019 - 501.951676 + 501.945573 - 504.355026 + 504.348893 - 517.332967 + 517.326677 - 536.078924 + 536.072405 - 545.692200 + 545.685564 - 549.537462 + 549.530779 - 541.366097 + 541.359514 - 536.559642 + 536.553118 - 526.946244 + 526.939836 - 531.752821 + 531.746355 - 558.189667 + 558.182879 - 561.554210 + 561.547381 - 556.747511 + 556.740740 - 543.288728 + 543.282122 - 515.410337 + 515.404069 - 493.780312 + 493.774308 - 503.393589 + 503.387467 - 516.371530 + 516.365251 - 530.310909 + 530.304460 - 539.443467 + 539.436907 - 550.979374 + 550.972674 - 559.631579 + 559.624774 - 558.670141 + 558.663348 - 558.670141 + 558.663348 - 562.515403 + 562.508563 - 566.841384 + 566.834491 - 568.764014 + 568.757098 - 564.438034 + 564.431170 - 556.266792 + 556.260028 - 552.902005 + 552.895281 - 557.708948 + 557.702166 - 561.073491 + 561.066668 - 568.764014 + 568.757098 - 571.647839 + 571.640887 - 571.167364 + 571.160419 - 563.957315 + 563.950458 - 557.708948 + 557.702166 - 558.670141 + 558.663348 - 579.338606 + 579.331561 - 586.548655 + 586.541523 - 594.239423 + 594.232197 - 600.488034 + 600.480732 - 606.736645 + 606.729267 - 612.504538 + 612.497090 - 626.443917 + 626.436299 - 633.653722 + 633.646016 - 637.979946 + 637.972188 - 639.421858 + 639.414083 - 639.902577 + 639.894796 - 637.018509 + 637.010763 - 637.018509 + 637.010763 - 633.173003 + 633.165303 - 626.443917 + 626.436299 - 613.946450 + 613.938984 - 603.852577 + 603.845234 - 592.316792 + 592.309589 - 585.106743 + 585.099628 - 579.819325 + 579.812274 - 572.609520 + 572.602557 - 565.399471 + 565.392596 - 563.476841 + 563.469989 - 569.244733 + 569.237811 - 575.493345 + 575.486347 - 578.377413 + 578.370380 - 576.935501 + 576.928485 - 571.167364 + 571.160419 - 566.841384 + 566.834491 - 555.305354 + 555.298602 - 545.211481 + 545.204851 - 536.559642 + 536.553118 - 527.426841 + 527.420427 - 518.774880 + 518.768571 - 514.448899 + 514.442643 - 513.487706 + 513.481462 - 509.161603 + 509.155412 - 505.797060 + 505.790910 - 504.835623 + 504.829484 - 507.719691 + 507.713517 - 508.680884 + 508.674699 - 508.680884 + 508.674699 - 503.393589 + 503.387467 - 503.393589 + 503.387467 - 500.509642 + 500.503556 - 497.625696 + 497.619645 - 498.587011 + 498.580949 - 500.990239 + 500.984147 - 500.029046 + 500.022965 - 499.067608 + 499.061539 - 500.029046 + 500.022965 - 497.144977 + 497.138932 - 495.702943 + 495.696915 - 501.951676 + 501.945573 - 501.470958 + 501.464860 - 500.509642 + 500.503556 - 499.067608 + 499.061539 - 497.625696 + 497.619645 - 497.144977 + 497.138932 - 496.664381 + 496.658341 - 499.548327 + 499.542252 - 500.990239 + 500.984147 - 501.470958 + 501.464860 - 500.990239 + 500.984147 - 499.548327 + 499.542252 - 501.470958 + 501.464860 - 505.316341 + 505.310197 - 513.487706 + 513.481462 - 521.658948 + 521.652605 - 522.620263 + 522.613908 - 522.620263 + 522.613908 - 523.581579 + 523.575212 - 525.504210 + 525.497820 - 526.946244 + 526.939836 - 528.868997 + 528.862566 - 528.868997 + 528.862566 - 482.244405 + 482.238541 - 482.244405 + 482.238541 - 499.067608 + 499.061539 - 500.990239 + 500.984147 - 504.835623 + 504.829484 - 501.951676 + 501.945573 - 498.587011 + 498.580949 - 498.106415 + 498.100358 - 498.587011 + 498.580949 - 497.144977 + 497.138932 - 497.625696 + 497.619645 - 500.029046 + 500.022965 - 500.029046 + 500.022965 - 501.470958 + 501.464860 - 503.393589 + 503.387467 - 504.835623 + 504.829484 - 511.084234 + 511.078019 - 525.504210 + 525.497820 - 519.736195 + 519.729875 - 518.774880 + 518.768571 - 517.813564 + 517.807268 - 515.890933 + 515.884660 - 516.371530 + 516.365251 - 515.410337 + 515.404069 - 518.774880 + 518.768571 - 519.255598 + 519.249284 - 517.813564 + 517.807268 - 514.448899 + 514.442643 - 513.968302 + 513.962053 - 517.332967 + 517.326677 - 518.774880 + 518.768571 - 522.139545 + 522.133195 - 527.907437 + 527.901018 - 541.366097 + 541.359514 - 550.979374 + 550.972674 - 560.112053 + 560.105243 - 567.802577 + 567.795672 - 574.532151 + 574.525165 - 581.261481 + 581.254413 - 585.587218 + 585.580097 - 588.471530 + 588.464374 - 586.067936 + 586.060810 - 578.858132 + 578.851093 - 573.090239 + 573.083270 - 574.051432 + 574.044452 - 580.300044 + 580.292987 - 588.471530 + 588.464374 - 592.797511 + 592.790302 - 597.603966 + 597.596699 - 609.139995 + 609.132588 - 616.349800 + 616.342305 - 630.769897 + 630.762227 - 639.421858 + 639.414083 - 639.902577 + 639.894796 - 641.825208 + 641.817403 - 644.228558 + 644.220724 - 649.996450 + 649.988546 - 654.322675 + 654.314718 - 656.245061 + 656.237082 - 655.764587 + 655.756613 - 649.996450 + 649.988546 - 633.653722 + 633.646016 - 624.521286 + 624.513692 - 622.117936 + 622.110371 - 618.272431 + 618.264912 - 615.869325 + 615.861836 - 614.427169 + 614.419697 - 609.139995 + 609.132588 - 603.852577 + 603.845234 - 595.681335 + 595.674091 - 592.316792 + 592.309589 - 575.493345 + 575.486347 - 567.322102 + 567.315204 - 573.090239 + 573.083270 - 583.183868 + 583.176776 - 582.222675 + 582.215595 - 580.780763 + 580.773700 - 576.935501 + 576.928485 - 570.205927 + 570.198993 - 566.841384 + 566.834491 - 573.570958 + 573.563983 - 579.819325 + 579.812274 - 582.222675 + 582.215595 - 574.051432 + 574.044452 - 571.647839 + 571.640887 - 572.609520 + 572.602557 - 570.205927 + 570.198993 - 552.421286 + 552.414568 - 541.366097 + 541.359514 - 525.984806 + 525.978410 - 513.968302 + 513.962053 - 503.393589 + 503.387467 - 506.758254 + 506.752091 - 535.598083 + 535.591570 - 559.150860 + 559.144061 - 567.322102 + 567.315204 - 571.647839 + 571.640887 - 569.244733 + 569.237811 - 541.846816 + 541.840227 - 541.846816 + 541.840227 - 549.537462 + 549.530779 - 554.824636 + 554.817889 - 559.631579 + 559.624774 - 554.344161 + 554.337420 - 545.211481 + 545.204851 - 532.714259 + 532.707781 - 516.852249 + 516.845964 - 510.122919 + 510.116716 - 513.968302 + 513.962053 - 525.023613 + 525.017229 - 538.482273 + 538.475725 - 547.614831 + 547.608172 - 559.150860 + 559.144061 - 573.090239 + 573.083270 - 578.858132 + 578.851093 - 567.322102 + 567.315204 - 556.266792 + 556.260028 - 544.250288 + 544.243670 - 532.233540 + 532.227068 - 534.636889 + 534.630388 - 538.962870 + 538.956316 - 537.040239 + 537.033709 - 525.984806 + 525.978410 - 518.774880 + 518.768571 - 510.603515 + 510.597306 - 493.299593 + 493.293595 - 482.725124 + 482.719254 - 485.128351 + 485.122452 - 467.824429 + 467.818741 - 456.769119 + 456.763564 - 447.636439 + 447.630996 - 441.868546 + 441.863173 - 439.465075 + 439.459731 - 428.409886 + 428.404677 - 421.199959 + 421.194838 - 415.912542 + 415.907484 - 421.680556 + 421.675429 - 432.255270 + 432.250014 - 426.006537 + 426.001356 - 420.719241 + 420.714125 - 429.851798 + 429.846571 - 438.503881 + 438.498549 - 441.387828 + 441.382460 - 441.387828 + 441.382460 - 438.984478 + 438.979140 - 436.100532 + 436.095229 - 432.735989 + 432.730727 - 431.774429 + 431.769179 - 429.851798 + 429.846571 - 432.255270 + 432.250014 - 438.503881 + 438.498549 - 448.597877 + 448.592422 - 456.769119 + 456.763564 - 458.691750 + 458.686172 - 456.288522 + 456.282974 - 445.713808 + 445.708388 - 443.791177 + 443.785781 - 442.829862 + 442.824477 - 441.868546 + 441.863173 - 446.675124 + 446.669692 - 447.636439 + 447.630996 - 449.078473 + 449.073012 - 450.520507 + 450.515029 - 457.249837 + 457.244277 - 453.885172 + 453.879653 - 450.039911 + 450.034438 - 450.520507 + 450.515029 - 448.597877 + 448.592422 - 448.597877 + 448.592422 - 447.155720 + 447.150283 - 438.023163 + 438.017836 - 435.139216 + 435.133925 - 433.697182 + 433.691908 - 427.448571 + 427.443373 - 426.967974 + 426.962782 - 423.122590 + 423.117445 - 423.122590 + 423.117445 - 423.122590 + 423.117445 - 418.796610 + 418.791517 - 406.299265 + 406.294325 - 403.896038 + 403.891126 - 401.492688 + 401.487806 - 400.050776 + 400.045911 - 399.089216 + 399.084363 - 409.183333 + 409.178358 - 408.222018 + 408.217054 - 403.896038 + 403.891126 - 402.934600 + 402.929700 - 397.166585 + 397.161756 - 395.243955 + 395.239148 - 394.763358 + 394.758558 - 391.398571 + 391.393811 - 391.398571 + 391.393811 - 389.475940 + 389.471204 - 386.592116 + 386.587415 - 377.940033 + 377.935437 - 375.056086 + 375.051526 - 374.094649 + 374.090100 - 373.133455 + 373.128918 - 372.652737 + 372.648205 - 370.249387 + 370.244885 - 366.884722 + 366.880261 - 366.884722 + 366.880261 - 364.962091 + 364.957653 - 359.674795 + 359.670422 - 359.674795 + 359.670422 - 356.790727 + 356.786388 - 355.348815 + 355.344494 - 361.116829 + 361.112438 - 357.271446 + 357.267101 - 356.310130 + 356.305798 - 355.829534 + 355.825207 - 353.906903 + 353.902599 - 353.426184 + 353.421886 - 350.061519 + 350.057262 - 346.696854 + 346.692638 - 346.696854 + 346.692638 - 345.254820 + 345.250621 - 344.774223 + 344.770031 - 344.774223 + 344.770031 - 348.619485 + 348.615246 - 351.022712 + 351.018444 - 351.022712 + 351.018444 - 354.387499 + 354.383190 - 356.790727 + 356.786388 - 362.558742 + 362.554333 - 373.133455 + 373.128918 - 377.940033 + 377.935437 - 381.304698 + 381.300061 - 381.304698 + 381.300061 - 384.188766 + 384.184094 - 385.150082 + 385.145398 - 253.928511 + 253.925423 - 253.928511 + 253.925423 diff --git a/reference/track/pcx.trk b/reference/track/pcx.trk new file mode 100644 index 000000000..1e07c73a1 --- /dev/null +++ b/reference/track/pcx.trk @@ -0,0 +1,73 @@ +H SOFTWARE NAME & VERSION +I PCX5 2.09 + +H R DATUM IDX DA DF DX DY DZ +M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 + +H COORDINATE SYSTEM +U LAT LON DM +H LATITUDE LONGITUDE DATE TIME ALT ;track +T N3003.73100 W09136.62100 25-MAY-02 17:06:21 1 +T N3003.76700 W09136.63400 25-MAY-02 17:09:55 0 +T N3003.76200 W09136.49600 25-MAY-02 17:12:00 0 +T N3003.74000 W09136.44300 25-MAY-02 17:12:48 0 +T N3003.69200 W09136.31700 25-MAY-02 17:14:41 0 +T N3003.58700 W09135.96400 25-MAY-02 17:17:16 0 +T N3003.46800 W09135.80100 25-MAY-02 17:17:46 0 +T N3003.32300 W09135.69400 25-MAY-02 17:18:20 0 +T N3003.23300 W09135.55700 25-MAY-02 17:19:01 0 +T N3002.98400 W09135.38500 25-MAY-02 17:20:46 0 +T N3002.94100 W09135.39300 25-MAY-02 17:21:10 0 +T N3002.92800 W09135.57600 25-MAY-02 17:21:51 0 +T N3002.77400 W09135.78700 25-MAY-02 17:22:35 0 +T N3002.73100 W09135.92300 25-MAY-02 17:23:08 0 +T N3002.83800 W09136.01600 25-MAY-02 18:04:23 0 +T N3002.82000 W09135.97800 25-MAY-02 18:06:04 2 +T N3002.78600 W09135.96800 25-MAY-02 18:07:06 0 +T N3002.77200 W09135.93700 25-MAY-02 18:08:18 1 +T N3002.78200 W09135.86400 25-MAY-02 18:10:20 0 +T N3002.78100 W09135.83000 25-MAY-02 18:11:09 0 +T N3002.80700 W09135.78000 25-MAY-02 18:12:18 0 +T N3002.84700 W09135.71200 25-MAY-02 18:14:22 0 +T N3002.86800 W09135.68600 25-MAY-02 18:15:04 2 +T N3002.89500 W09135.64500 25-MAY-02 18:16:14 1 +T N3002.92100 W09135.62800 25-MAY-02 18:17:01 1 +T N3002.96100 W09135.63100 25-MAY-02 18:18:07 0 +T N3003.01900 W09135.63900 25-MAY-02 18:19:51 2 +T N3003.04700 W09135.64700 25-MAY-02 18:20:39 0 +T N3003.07400 W09135.66200 25-MAY-02 18:21:24 0 +T N3003.10800 W09135.66200 25-MAY-02 18:22:17 0 +T N3003.13300 W09135.68000 25-MAY-02 18:23:18 0 +T N3003.18100 W09135.68100 25-MAY-02 18:24:37 0 +T N3003.29200 W09135.71200 25-MAY-02 18:28:13 6 +T N3003.22400 W09135.69600 25-MAY-02 18:31:36 2 +T N3003.19100 W09135.68700 25-MAY-02 18:32:56 0 +T N3003.15800 W09135.69000 25-MAY-02 18:34:02 0 +T N3003.14700 W09135.72600 25-MAY-02 18:36:03 0 +T N3003.14900 W09135.75800 25-MAY-02 18:36:48 0 +T N3003.15900 W09135.80700 25-MAY-02 18:37:52 1 +T N3003.18800 W09135.87100 25-MAY-02 18:39:18 0 +T N3003.21700 W09135.87800 25-MAY-02 18:40:15 0 +T N3003.23800 W09135.86600 25-MAY-02 18:41:25 6 +T N3003.21700 W09135.88500 25-MAY-02 18:42:37 0 +T N3003.19200 W09135.87500 25-MAY-02 18:44:01 0 +T N3003.16900 W09135.85100 25-MAY-02 18:45:53 0 +T N3003.15400 W09135.81600 25-MAY-02 18:46:54 0 +T N3003.14000 W09135.78600 25-MAY-02 18:47:42 0 +T N3003.13500 W09135.74100 25-MAY-02 18:48:41 0 +T N3003.13300 W09135.70100 25-MAY-02 18:49:52 0 +T N3003.11300 W09135.68200 25-MAY-02 18:50:49 0 +T N3003.06300 W09135.66400 25-MAY-02 18:52:14 0 +T N3003.03400 W09135.65400 25-MAY-02 18:52:56 0 +T N3003.01100 W09135.64600 25-MAY-02 18:53:38 0 +T N3002.94600 W09135.62300 25-MAY-02 18:55:11 0 +T N3002.90700 W09135.65500 25-MAY-02 18:56:32 0 +T N3002.88500 W09135.68500 25-MAY-02 18:57:24 0 +T N3002.85000 W09135.72700 25-MAY-02 18:58:40 7 +T N3002.82400 W09135.76000 25-MAY-02 18:59:28 0 +T N3002.79800 W09135.79600 25-MAY-02 19:00:22 0 +T N3002.78400 W09135.85900 25-MAY-02 19:01:41 0 +T N3002.77400 W09135.90800 25-MAY-02 19:02:48 0 +T N3002.77900 W09135.93800 25-MAY-02 19:03:43 0 +T N3002.80700 W09135.95700 25-MAY-02 19:04:49 0 +T N3002.82800 W09135.98000 25-MAY-02 19:05:57 0 diff --git a/reference/track/simpletrack.gpx b/reference/track/simpletrack.gpx new file mode 100644 index 000000000..7e760af8e --- /dev/null +++ b/reference/track/simpletrack.gpx @@ -0,0 +1,21 @@ + + + + + + +1.000000 + + + +0.000000 + + + + + diff --git a/reference/track/sportsim-sample.txt b/reference/track/sportsim-sample.txt new file mode 100644 index 000000000..8ec28aac5 --- /dev/null +++ b/reference/track/sportsim-sample.txt @@ -0,0 +1,66 @@ +SportsimVersion:01 +#Sportsim TrackFile +00000;0;30.062183;-91.610350;3;1022346381; +00001;0;30.062783;-91.610567;-328083987;1022346595; +00002;0;30.062700;-91.608267;-328083987;1022346720; +00003;0;30.062333;-91.607383;-328083987;1022346768; +00004;0;30.061533;-91.605283;-328083987;1022346881; +00005;0;30.059783;-91.599400;-328083987;1022347036; +00006;0;30.057800;-91.596683;-328083987;1022347066; +00007;0;30.055383;-91.594900;-328083987;1022347100; +00008;0;30.053883;-91.592617;-328083987;1022347141; +00009;0;30.049733;-91.589750;-328083987;1022347246; +00010;0;30.049017;-91.589883;-328083987;1022347270; +00011;0;30.048800;-91.592933;-328083987;1022347311; +00012;0;30.046233;-91.596450;-328083987;1022347355; +00013;0;30.045517;-91.598717;-328083987;1022347388; +00014;0;30.047300;-91.600267;-328083987;1022349863; +00015;0;30.047000;-91.599633;7;1022349964; +00016;0;30.046433;-91.599467;-328083987;1022350026; +00017;0;30.046200;-91.598950;3;1022350098; +00018;0;30.046367;-91.597733;-328083987;1022350220; +00019;0;30.046350;-91.597167;-328083987;1022350269; +00020;0;30.046783;-91.596333;-328083987;1022350338; +00021;0;30.047450;-91.595200;-328083987;1022350462; +00022;0;30.047800;-91.594767;7;1022350504; +00023;0;30.048250;-91.594083;3;1022350574; +00024;0;30.048683;-91.593800;3;1022350621; +00025;0;30.049350;-91.593850;-328083987;1022350687; +00026;0;30.050317;-91.593983;7;1022350791; +00027;0;30.050783;-91.594117;-328083987;1022350839; +00028;0;30.051233;-91.594367;-328083987;1022350884; +00029;0;30.051800;-91.594367;-328083987;1022350937; +00030;0;30.052217;-91.594667;-328083987;1022350998; +00031;0;30.053017;-91.594683;-328083987;1022351077; +00032;0;30.054867;-91.595200;20;1022351293; +00033;0;30.053733;-91.594933;7;1022351496; +00034;0;30.053183;-91.594783;-328083987;1022351576; +00035;0;30.052633;-91.594833;-328083987;1022351642; +00036;0;30.052450;-91.595433;-328083987;1022351763; +00037;0;30.052483;-91.595967;-328083987;1022351808; +00038;0;30.052650;-91.596783;3;1022351872; +00039;0;30.053133;-91.597850;-328083987;1022351958; +00040;0;30.053617;-91.597967;-328083987;1022352015; +00041;0;30.053967;-91.597767;20;1022352085; +00042;0;30.053617;-91.598083;-328083987;1022352157; +00043;0;30.053200;-91.597917;-328083987;1022352241; +00044;0;30.052817;-91.597517;-328083987;1022352353; +00045;0;30.052567;-91.596933;-328083987;1022352414; +00046;0;30.052333;-91.596433;-328083987;1022352462; +00047;0;30.052250;-91.595683;-328083987;1022352521; +00048;0;30.052217;-91.595017;-328083987;1022352592; +00049;0;30.051883;-91.594700;-328083987;1022352649; +00050;0;30.051050;-91.594400;-328083987;1022352734; +00051;0;30.050567;-91.594233;-328083987;1022352776; +00052;0;30.050183;-91.594100;-328083987;1022352818; +00053;0;30.049100;-91.593717;-328083987;1022352911; +00054;0;30.048450;-91.594250;-328083987;1022352992; +00055;0;30.048083;-91.594750;-328083987;1022353044; +00056;0;30.047500;-91.595450;23;1022353120; +00057;0;30.047067;-91.596000;-328083987;1022353168; +00058;0;30.046633;-91.596600;-328083987;1022353222; +00059;0;30.046400;-91.597650;-328083987;1022353301; +00060;0;30.046233;-91.598467;-328083987;1022353368; +00061;0;30.046317;-91.598967;-328083987;1022353423; +00062;0;30.046783;-91.599283;-328083987;1022353489; +00063;0;30.047133;-91.599667;-328083987;1022353557; diff --git a/reference/track/stmsdf-track.sdf b/reference/track/stmsdf-track.sdf new file mode 100644 index 000000000..1d5f4f51e --- /dev/null +++ b/reference/track/stmsdf-track.sdf @@ -0,0 +1,99 @@ +[HEADER] +FILEVERSION=1 +SOURCE=FILE +DATUM=WGS84 +TYPE=28 +NAME=ACTIVE LOG 006 +MINALT=130 +MAXALT=161 +MAXSPEED=11.42 +DISTANCE=653 +DURATION=1989 +DATE=01.05.2005 15:02.47 +AVGSPEED=0.33 +[POINTS] +"TP",01.05.2005,15:02.47,51.312938,12.413165,161,0.00,0.0,0 +"TP",01.05.2005,15:03.25,51.312883,12.413248,154,0.22,136.9,8.478119 +"TP",01.05.2005,15:03.39,51.312855,12.413248,148,0.22,180.0,11.566578 +"TP",01.05.2005,15:04.16,51.312827,12.413304,139,0.13,128.7,16.521235 +"TP",01.05.2005,15:05.02,51.312827,12.413276,145,0.04,270.0,18.457564 +"TP",01.05.2005,15:05.45,51.312827,12.413304,134,0.05,90.0,20.393893 +"TP",01.05.2005,15:06.44,51.312772,12.413332,131,0.11,162.6,26.865457 +"TP",01.05.2005,15:07.50,51.312772,12.413332,130,0.00,0.0,26.865457 +"TP",01.05.2005,15:08.19,51.312744,12.413332,132,0.11,180.0,29.963246 +"TP",01.05.2005,15:11.16,51.312799,12.413304,144,0.04,342.7,36.443717 +"TP",01.05.2005,15:12.34,51.312911,12.413443,147,0.20,38.0,52.143218 +"TP",01.05.2005,15:13.18,51.312994,12.413804,145,0.61,69.7,78.925927 +"TP",01.05.2005,15:13.27,51.313049,12.413804,145,0.69,0.0,85.112175 +"TP",01.05.2005,15:13.37,51.313049,12.413832,135,0.19,90.0,87.042662 +"TP",01.05.2005,15:13.46,51.313105,12.413832,135,0.69,0.0,93.219581 +"TP",01.05.2005,15:14.03,51.313216,12.413887,136,0.76,17.4,106.182252 +"TP",01.05.2005,15:14.16,51.313299,12.413971,135,0.84,32.0,117.119734 +"TP",01.05.2005,15:14.26,51.313272,12.414054,139,0.66,118.0,123.688361 +"TP",01.05.2005,15:14.30,51.313272,12.414110,139,0.97,90.0,127.555149 +"TP",01.05.2005,15:15.06,51.313049,12.414610,141,1.19,125.4,170.241955 +"TP",01.05.2005,15:15.27,51.312966,12.414832,140,0.86,121.0,188.281604 +"TP",01.05.2005,15:15.39,51.312911,12.414943,140,0.82,128.6,198.174693 +"TP",01.05.2005,15:25.31,51.312938,12.414971,152,0.01,32.1,201.819955 +"TP",01.05.2005,15:25.40,51.312938,12.414971,152,0.00,0.0,201.819955 +"TP",01.05.2005,15:29.18,51.312966,12.414943,155,0.02,327.9,205.465216 +"TP",01.05.2005,15:30.30,51.313160,12.414582,149,0.46,310.7,238.629832 +"TP",01.05.2005,15:30.37,51.313160,12.414554,150,0.28,270.0,240.560315 +"TP",01.05.2005,15:30.47,51.313160,12.414443,151,0.77,270.0,248.293911 +"TP",01.05.2005,15:30.48,51.313160,12.414387,151,3.87,270.0,252.160708 +"TP",01.05.2005,15:30.52,51.313327,12.413915,150,9.43,299.5,289.898474 +"TP",01.05.2005,15:30.57,51.313688,12.413332,150,11.42,314.7,347.021422 +"TP",01.05.2005,15:31.03,51.313994,12.412860,150,7.88,316.0,394.311899 +"TP",01.05.2005,15:31.10,51.314216,12.412498,150,5.04,314.6,429.569729 +"TP",01.05.2005,15:32.38,51.314633,12.409554,143,2.39,282.8,639.630841 +"TP",01.05.2005,15:32.45,51.314633,12.409499,141,0.55,270.0,643.491682 +"TP",01.05.2005,15:33.17,51.314633,12.409499,143,0.00,0.0,643.491682 +"TP",01.05.2005,15:33.42,51.314633,12.409443,139,0.15,270.0,647.358356 +"TP",01.05.2005,15:33.54,51.314633,12.409360,139,0.48,270.0,653.161283 +"TP",01.05.2005,15:34.04,51.314633,12.409360,138,0.00,0.0,653.161283 +"TP",01.05.2005,15:34.20,51.314633,12.409360,139,0.00,0.0,653.161283 +"TP",01.05.2005,15:35.45,51.314633,12.409360,144,0.00,0.0,653.161283 +"TP",01.05.2005,15:35.56,51.314633,12.409360,145,0.00,0.0,653.161283 +[CUSTOM1] +0,161 +38,154 +52,148 +89,139 +135,145 +178,134 +237,131 +303,130 +332,132 +509,144 +587,147 +631,145 +640,145 +650,135 +659,135 +676,136 +689,135 +699,139 +703,139 +739,141 +760,140 +772,140 +1364,152 +1373,152 +1591,155 +1663,149 +1670,150 +1680,151 +1681,151 +1685,150 +1690,150 +1696,150 +1703,150 +1791,143 +1798,141 +1830,143 +1855,139 +1867,139 +1877,138 +1893,139 +1978,144 +1989,145 diff --git a/reference/track/stmwpp-track.gpx b/reference/track/stmwpp-track.gpx new file mode 100644 index 000000000..f6204f68f --- /dev/null +++ b/reference/track/stmwpp-track.gpx @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/track/stmwpp-track.txt b/reference/track/stmwpp-track.txt new file mode 100644 index 000000000..fda1fa51d --- /dev/null +++ b/reference/track/stmwpp-track.txt @@ -0,0 +1,54 @@ +Datum,WGS 84,WGS 84,0,0,0,0,0 +TP,D,45.187113,4.6607297,08/23/2005,15:25:12.812, +TP,D,45.1868455,4.660163,08/23/2005,15:25:22.822, +TP,D,45.1863955,4.6599324,08/23/2005,15:25:39.839, +TP,D,45.1859246,4.6598826,08/23/2005,15:25:58.858, +TP,D,45.185478,4.6597676,08/23/2005,15:26:16.816, +TP,D,45.1850178,4.6597388,08/23/2005,15:26:33.833, +TP,D,45.1845797,4.6596044,08/23/2005,15:26:53.853, +TP,D,45.1841254,4.6596267,08/23/2005,15:27:09.89, +TP,D,45.1836672,4.6595521,08/23/2005,15:27:28.828, +TP,D,45.1836814,4.6588984,08/23/2005,15:28:02.82, +TP,D,45.183994,4.6584016,08/23/2005,15:28:15.815, +TP,D,45.1846076,4.657295,08/23/2005,15:28:30.830, +TP,D,45.1850065,4.6558776,08/23/2005,15:28:44.844, +TP,D,45.1845094,4.6552681,08/23/2005,15:28:54.854, +TP,D,45.1839276,4.6546767,08/23/2005,15:29:04.84, +TP,D,45.1834919,4.6543834,08/23/2005,15:29:16.816, +TP,D,45.1835007,4.6537414,08/23/2005,15:29:26.826, +TP,D,45.1833348,4.6531515,08/23/2005,15:29:42.842, +TP,D,45.1830662,4.6526252,08/23/2005,15:29:59.859, +TP,D,45.1830017,4.6519839,08/23/2005,15:30:15.815, +TP,D,45.1829897,4.6513269,08/23/2005,15:30:32.832, +TP,D,45.1829101,4.6506828,08/23/2005,15:30:44.844, +TP,D,45.1825391,4.6502882,08/23/2005,15:30:56.856, +TP,D,45.1821259,4.6499932,08/23/2005,15:31:14.814, +TP,D,45.1817943,4.6495713,08/23/2005,15:31:31.831, +TP,D,45.1816251,4.6489743,08/23/2005,15:31:50.850, +TP,D,45.1815118,4.6483493,08/23/2005,15:32:13.813, +TP,D,45.1812957,4.647775,08/23/2005,15:32:34.834, +TP,D,45.181057,4.6472012,08/23/2005,15:32:56.856, +TP,D,45.1807201,4.6467576,08/23/2005,15:33:15.815, +TP,D,45.1804336,4.6462213,08/23/2005,15:33:32.832, +TP,D,45.180078,4.6458228,08/23/2005,15:33:51.851, +TP,D,45.1796982,4.6454427,08/23/2005,15:34:09.89, +TP,D,45.1793545,4.6450331,08/23/2005,15:34:29.829, +TP,D,45.1788317,4.644899,08/23/2005,15:34:50.850, +TP,D,45.1788737,4.6442499,08/23/2005,15:35:15.815, +TP,D,45.1791315,4.6437253,08/23/2005,15:35:33.833, +TP,D,45.17924,4.6431102,08/23/2005,15:35:55.855, +TP,D,45.179606,4.6427364,08/23/2005,15:36:16.816, +TP,D,45.1797593,4.6421412,08/23/2005,15:36:39.839, +TP,D,45.1798951,4.6415263,08/23/2005,15:37:03.83, +TP,D,45.1799366,4.6408842,08/23/2005,15:37:33.833, +TP,D,45.1796929,4.6403555,08/23/2005,15:38:06.86, +TP,D,45.1797172,4.6397143,08/23/2005,15:38:36.836, +TP,D,45.1795321,4.6391257,08/23/2005,15:39:06.86, +TP,D,45.179173,4.6387332,08/23/2005,15:39:29.829, +TP,D,45.1790175,4.6381358,08/23/2005,15:39:51.851, +TP,D,45.1788947,4.6375252,08/23/2005,15:40:14.814, +TP,D,45.1786746,4.6369489,08/23/2005,15:40:34.834, +TP,D,45.1783918,4.6364349,08/23/2005,15:40:47.847, +TP,D,45.1781717,4.6358662,08/23/2005,15:40:59.859, +TP,D,45.1778664,4.6351585,08/23/2005,15:41:09.89, +TP,D,45.1774999,4.6345872,08/23/2005,15:41:19.819, diff --git a/reference/track/tinterptrack.gpx b/reference/track/tinterptrack.gpx new file mode 100644 index 000000000..3a04e3a2f --- /dev/null +++ b/reference/track/tinterptrack.gpx @@ -0,0 +1,58 @@ + + + + + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/tpo-sample1.gpx b/reference/track/tpo-sample1.gpx new file mode 100644 index 000000000..1fa265665 --- /dev/null +++ b/reference/track/tpo-sample1.gpx @@ -0,0 +1,4839 @@ + + + + + + Track 1 + + + 0.000000 + + + 0.000000 + + + + + Track 2 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 3 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 4 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 5 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 6 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 7 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 8 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 9 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 10 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 11 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 12 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 13 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 14 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 15 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 16 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 17 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 18 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 19 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 20 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 21 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 22 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 23 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 24 + + + 0.000000 + + + 0.000000 + + + + + Track 25 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 26 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 27 + + + 0.000000 + + + 0.000000 + + + + + Track 28 + + + 0.000000 + + + 0.000000 + + + + + Track 29 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 30 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + 0.000000 + + + + + Track 31 + + + 0.000000 + + + 0.000000 + + + + diff --git a/reference/track/tpo-sample1.tpo b/reference/track/tpo-sample1.tpo new file mode 100644 index 0000000000000000000000000000000000000000..6c3751e1fd8537037ac773aeca3f299839c68f54 GIT binary patch literal 9293 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 + + + + 03-SEP-05 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 339.963379 + + + 72.236206 + + + 74.158813 + + + 70.794189 + + + 68.390869 + + + 68.871582 + + + 69.352295 + + + 70.794189 + + + 69.352295 + + + 65.507080 + + + 64.545654 + + + 65.026367 + + + 65.026367 + + + 64.545654 + + + 63.584351 + + + 64.545654 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 62.142334 + + + 58.777710 + + + 60.219727 + + + 59.739136 + + + 61.661743 + + + 62.142334 + + + 61.181030 + + + 57.335815 + + + 50.606567 + + + 49.164551 + + + 47.722534 + + + 44.358032 + + + 44.838623 + + + 48.203369 + + + 47.241821 + + + 46.761230 + + + 75.120239 + + + 75.120239 + + + 64.545654 + + + 57.335815 + + + 52.048584 + + + 49.645264 + + + 45.319214 + + + 45.319214 + + + 48.683960 + + + 46.280640 + + + 45.319214 + + + 47.241821 + + + 50.125977 + + + 54.451782 + + + 55.893799 + + + 57.816528 + + + 56.855103 + + + 59.258423 + + + 60.219727 + + + 63.103638 + + + 63.584351 + + + 64.545654 + + + 66.468262 + + + 67.429688 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.468262 + + + 68.390869 + + + 70.313477 + + + 72.236206 + + + 75.600830 + + + 77.523438 + + + 77.523438 + + + 77.042847 + + + 78.004028 + + + 78.004028 + + + 77.042847 + + + 77.523438 + + + 77.042847 + + + 76.081421 + + + 74.158813 + + + 72.236206 + + + 71.274902 + + + 72.236206 + + + 73.197632 + + + 74.639526 + + + 75.600830 + + + 75.600830 + + + 75.120239 + + + 74.158813 + + + 76.081421 + + + 76.081421 + + + 75.120239 + + + 73.197632 + + + 72.716919 + + + 74.158813 + + + 74.158813 + + + 74.158813 + + + 74.639526 + + + 74.639526 + + + 72.236206 + + + 72.716919 + + + 75.600830 + + + 79.446045 + + + 80.407471 + + + 84.733398 + + + 85.694580 + + + 89.059326 + + + 89.059326 + + + 91.943237 + + + 92.904541 + + + 93.865845 + + + 93.865845 + + + 93.865845 + + + + + 03-SEP-05 02 +1 + + + 282.765015 + + + 53.009766 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 346.212036 + + + 339.963379 + + + 72.236206 + + + 74.158813 + + + 70.794189 + + + 68.390869 + + + 68.871582 + + + 69.352295 + + + 70.794189 + + + 69.352295 + + + 65.507080 + + + 64.545654 + + + 65.026367 + + + 65.026367 + + + 64.545654 + + + 63.584351 + + + 64.545654 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 65.507080 + + + 62.142334 + + + 58.777710 + + + 60.219727 + + + 59.739136 + + + 61.661743 + + + 62.142334 + + + 61.181030 + + + 57.335815 + + + 50.606567 + + + 49.164551 + + + 47.722534 + + + 44.358032 + + + 44.838623 + + + 48.203369 + + + 47.241821 + + + 46.761230 + + + 75.120239 + + + 75.120239 + + + 64.545654 + + + 57.335815 + + + 52.048584 + + + 49.645264 + + + 45.319214 + + + 45.319214 + + + 48.683960 + + + 46.280640 + + + 45.319214 + + + 47.241821 + + + 50.125977 + + + 54.451782 + + + 55.893799 + + + 57.816528 + + + 56.855103 + + + 59.258423 + + + 60.219727 + + + 63.103638 + + + 63.584351 + + + 64.545654 + + + 66.468262 + + + 67.429688 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.948975 + + + 66.468262 + + + 68.390869 + + + 70.313477 + + + 72.236206 + + + 75.600830 + + + 77.523438 + + + 77.523438 + + + 77.042847 + + + 78.004028 + + + 78.004028 + + + 77.042847 + + + 77.523438 + + + 77.042847 + + + 76.081421 + + + 74.158813 + + + 72.236206 + + + 71.274902 + + + 72.236206 + + + 73.197632 + + + 74.639526 + + + 75.600830 + + + 75.600830 + + + 75.120239 + + + 74.158813 + + + 76.081421 + + + 76.081421 + + + 75.120239 + + + 73.197632 + + + 72.716919 + + + 74.158813 + + + 74.158813 + + + 74.158813 + + + 74.639526 + + + 74.639526 + + + 72.236206 + + + 72.716919 + + + 75.600830 + + + 79.446045 + + + 80.407471 + + + 84.733398 + + + 85.694580 + + + 89.059326 + + + 89.059326 + + + 91.943237 + + + 92.904541 + + + 93.865845 + + + 93.865845 + + + 93.865845 + + + 98.672485 + + + 99.633789 + + + 100.114502 + + + 98.672485 + + + 97.711182 + + + 96.269287 + + + 95.788452 + + + 95.788452 + + + 94.827148 + + + 91.943237 + + + 90.981934 + + + 89.539917 + + + 87.136597 + + + 87.617188 + + + 88.098022 + + + 88.578735 + + + 90.501343 + + + 90.020630 + + + + + 03-SEP-05 03 +2 + + + 90.020630 + + + 92.423950 + + + 93.865845 + + + 90.501343 + + + 90.501343 + + + 93.865845 + + + 100.114502 + + + 103.479004 + + + 103.479004 + + + 103.479004 + + + 105.401733 + + + 105.401733 + + + 106.363037 + + + 106.363037 + + + 106.363037 + + + 103.959717 + + + 105.401733 + + + 107.805054 + + + 107.805054 + + + 105.882446 + + + 106.843628 + + + 106.363037 + + + 106.363037 + + + 104.921021 + + + 103.479004 + + + 102.517700 + + + 101.556396 + + + 101.075684 + + + 101.556396 + + + 100.595093 + + + 99.633789 + + + 98.672485 + + + 98.672485 + + + 98.191895 + + + 95.788452 + + + + + ACTIVE LOG +3 + + + 90.020630 + + + + 92.423950 + + + + 93.865845 + + + + 90.501343 + + + + 90.501343 + + + + 93.865845 + + + + 100.114502 + + + + 103.479004 + + + + 103.479004 + + + + 103.479004 + + + + 105.401733 + + + + 105.401733 + + + + 106.363037 + + + + 106.363037 + + + + 106.363037 + + + + 103.959717 + + + + 105.401733 + + + + 107.805054 + + + + 107.805054 + + + + 105.882446 + + + + 106.843628 + + + + 106.363037 + + + + 106.363037 + + + + 104.921021 + + + + 103.479004 + + + + 102.517700 + + + + 101.556396 + + + + 101.075684 + + + + 101.556396 + + + + 100.595093 + + + + 99.633789 + + + + 98.672485 + + + + 98.672485 + + + + 98.191895 + + + + 95.788452 + + + + + + ACTIVE LOG #2 +4 + + + 95.788452 + + + + 99.633789 + + + + 98.191895 + + + + 98.191895 + + + + 98.672485 + + + + 100.595093 + + + + 101.556396 + + + + 101.556396 + + + + 102.037109 + + + + 101.075684 + + + + 101.556396 + + + + 101.556396 + + + + 102.037109 + + + + 102.517700 + + + + 102.517700 + + + + 104.921021 + + + + 104.921021 + + + + 104.921021 + + + + 104.921021 + + + + 103.959717 + + + + 103.479004 + + + + 101.075684 + + + + 101.075684 + + + + 101.075684 + + + + 100.114502 + + + + 97.711182 + + + + 97.711182 + + + + 96.749878 + + + + 90.020630 + + + + 87.617188 + + + + 84.733398 + + + + 80.888184 + + + + 79.446045 + + + + 77.042847 + + + + 70.794189 + + + + 70.794189 + + + + 69.352295 + + + + 65.507080 + + + + 64.545654 + + + + 64.545654 + + + + 64.545654 + + + + 57.335815 + + + + 55.413086 + + + + 54.932373 + + + + 55.413086 + + + + 24.651001 + + + + 18.883057 + + + + 19.363770 + + + + 19.363770 + + + + 19.844360 + + + + 19.844360 + + + + 19.844360 + + + + 16.479736 + + + + 15.999023 + + + + 14.557007 + + + + 15.518433 + + + + 13.115112 + + + + 11.673218 + + + + 11.673218 + + + + 8.789185 + + + + 5.905273 + + + + 3.501953 + + + + 3.982666 + + + + 8.308594 + + + + 5.424561 + + + + 3.501953 + + + + 2.540649 + + + + 2.540649 + + + + 0.137451 + + + + 0.137451 + + + + 2.540649 + + + + -0.824097 + + + + -1.304688 + + + + -1.304688 + + + + -0.824097 + + + + -0.824097 + + + + 0.618042 + + + + 0.618042 + + + + -0.824097 + + + + 0.137451 + + + + 0.137451 + + + + -0.824097 + + + + -1.785278 + + + + -3.227295 + + + + -4.188599 + + + + -5.630493 + + + + -7.553101 + + + + -9.475830 + + + + -10.437256 + + + + -10.917847 + + + + -13.321045 + + + + -12.359863 + + + + -11.398438 + + + + -11.398438 + + + + -11.398438 + + + + -11.398438 + + + + -9.475830 + + + + -8.514648 + + + + -8.514648 + + + + -7.553101 + + + + -7.072510 + + + + -8.033936 + + + + -7.553101 + + + + -8.995239 + + + + 3.021240 + + + + 3.021240 + + + + 3.982666 + + + + 5.424561 + + + + 2.540649 + + + + -0.824097 + + + + -5.149902 + + + + -3.707886 + + + + -6.591919 + + + + 0.618042 + + + + 3.501953 + + + + 1.579346 + + + + -2.265991 + + + + -5.630493 + + + + -4.669312 + + + + -6.591919 + + + + -7.553101 + + + + -1.304688 + + + + 7.827881 + + + + 12.153809 + + + + 12.634399 + + + + 11.673218 + + + + 18.402344 + + + + 14.076416 + + + + 3.501953 + + + + 3.021240 + + + + + + ACTIVE LOG #3 +5 + + + 23.689575 + + + + 16.479736 + + + + 14.557007 + + + + 15.037720 + + + + 14.557007 + + + + 14.557007 + + + + 14.557007 + + + + 15.037720 + + + + 12.634399 + + + + 7.347168 + + + + 5.905273 + + + + 4.943848 + + + + 4.943848 + + + + 4.943848 + + + + 1.579346 + + + + 1.579346 + + + + 2.540649 + + + + 2.540649 + + + + 0.618042 + + + + 4.943848 + + + + 5.424561 + + + + 2.540649 + + + + 0.618042 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + -1.304688 + + + + -0.343384 + + + + -0.343384 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + 0.137451 + + + + + + ACTIVE LOG #4 +6 + + + 1.579346 + + + + 2.060059 + + + + 2.060059 + + + + 2.060059 + + + + 2.060059 + + + + + + ACTIVE LOG #5 +7 + + + 4.463257 + + + + 7.827881 + + + + 10.711792 + + + + 13.595825 + + + + 17.921753 + + + + 17.441162 + + + + 17.441162 + + + + 17.441162 + + + + 18.883057 + + + + 18.883057 + + + + 18.883057 + + + + 18.883057 + + + + + + ACTIVE LOG #6 +8 + + + 53.971191 + + + + 53.971191 + + + + 50.125977 + + + + 57.335815 + + + + 55.893799 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 54.451782 + + + + 51.087158 + + + + 48.203369 + + + + 48.203369 + + + + 47.722534 + + + + 46.280640 + + + + 45.319214 + + + + 45.319214 + + + + 43.396606 + + + + + + ACTIVE LOG #7 +9 + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 71.274902 + + + + 69.352295 + + + + 67.910278 + + + + 57.816528 + + + + 52.529175 + + + + 50.606567 + + + + 46.280640 + + + + 43.877319 + + + + 43.396606 + + + + 42.435425 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 41.954712 + + + + 38.590088 + + + + 38.109375 + + + + 38.109375 + + + + 37.628662 + + + + 39.070679 + + + + 48.683960 + + + + 50.125977 + + + + 49.645264 + + + + 49.164551 + + + + 49.164551 + + + + 46.280640 + + + + 43.396606 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 42.916016 + + + + 38.109375 + + + + 33.783447 + + + + 31.860718 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 31.380127 + + + + 30.899536 + + + + 30.418823 + + + + 29.938110 + + + + 11.673218 + + + + 11.673218 + + + + 11.192505 + + + + 11.192505 + + + + 10.711792 + + + + 10.711792 + + + + 11.673218 + + + + 10.711792 + + + + 10.711792 + + + + 10.711792 + + + + 11.673218 + + + + 11.673218 + + + + 10.711792 + + + + 8.789185 + + + + 6.385864 + + + + 6.385864 + + + + 6.385864 + + + + + + ACTIVE LOG #8 +10 + + + -4.188599 + + + + -6.111206 + + + + -5.630493 + + + + -0.824097 + + + + 0.618042 + + + + -0.343384 + + + + -0.343384 + + + + -0.824097 + + + + + + ACTIVE LOG #9 +11 + + + -0.824097 + + + + -0.824097 + + + + -0.343384 + + + + -0.824097 + + + + -0.824097 + + + + -0.824097 + + + + 0.618042 + + + + 1.579346 + + + + 3.021240 + + + + 3.021240 + + + + 5.424561 + + + + 9.269897 + + + + 9.269897 + + + + 9.750610 + + + + 13.595825 + + + + 15.037720 + + + + 15.518433 + + + + 18.402344 + + + + 19.363770 + + + + 19.363770 + + + + 19.363770 + + + + 22.728271 + + + + 24.170288 + + + + 24.651001 + + + + 26.573608 + + + + 28.496216 + + + + 31.860718 + + + + 31.860718 + + + + 31.860718 + + + + 31.860718 + + + + 31.860718 + + + + 32.341553 + + + + 33.783447 + + + + 33.783447 + + + + 33.783447 + + + + 37.148071 + + + + 41.954712 + + + + 42.435425 + + + + 47.722534 + + + + 48.203369 + + + + 48.203369 + + + + 54.451782 + + + + 58.297119 + + + + 60.700317 + + + + 60.700317 + + + + 60.700317 + + + + 60.700317 + + + + 60.700317 + + + + 65.026367 + + + + 68.871582 + + + + 68.871582 + + + + 68.871582 + + + + + + ACTIVE LOG #10 +12 + + + 96.749878 + + + + 90.501343 + + + + 90.020630 + + + + 90.981934 + + + + 91.462524 + + + + 91.462524 + + + + 91.462524 + + + + 91.943237 + + + + 91.462524 + + + + 90.020630 + + + + 87.136597 + + + + 87.136597 + + + + 87.617188 + + + + 88.578735 + + + + 88.098022 + + + + 88.098022 + + + + 87.617188 + + + + 86.175293 + + + + 86.175293 + + + + 83.771973 + + + + 83.291382 + + + + 83.771973 + + + + 83.771973 + + + + 78.004028 + + + + 72.716919 + + + + 70.794189 + + + + 70.794189 + + + + 69.352295 + + + + 68.390869 + + + + 68.871582 + + + + 66.948975 + + + + 63.103638 + + + + 57.335815 + + + + 57.335815 + + + + 54.932373 + + + + 54.451782 + + + + 52.048584 + + + + 52.048584 + + + + 44.358032 + + + + 41.473999 + + + + 41.473999 + + + + 37.628662 + + + + 35.706055 + + + + 34.264160 + + + + 31.860718 + + + + 24.651001 + + + + 22.247559 + + + + 20.324951 + + + + 18.402344 + + + + 20.805664 + + + + 16.479736 + + + + 16.479736 + + + + 15.518433 + + + + 12.634399 + + + + 12.634399 + + + + 8.308594 + + + + 2.060059 + + + + 0.618042 + + + + 0.618042 + + + + -0.343384 + + + + 0.618042 + + + + 0.137451 + + + + -2.265991 + + + + -1.304688 + + + + -1.785278 + + + + -1.785278 + + + + -3.227295 + + + + -3.227295 + + + + -2.265991 + + + + -2.265991 + + + + -2.265991 + + + + -0.824097 + + + + 3.021240 + + + + -0.824097 + + + + 3.982666 + + + + 0.137451 + + + + -3.227295 + + + + -2.746704 + + + + -2.265991 + + + + -4.188599 + + + + -7.072510 + + + + -6.591919 + + + + -4.669312 + + + + -4.669312 + + + + -8.033936 + + + + -3.227295 + + + + -3.227295 + + + + -1.785278 + + + + -1.304688 + + + + 0.137451 + + + + -1.304688 + + + + -2.265991 + + + + -2.265991 + + + + -3.707886 + + + + -4.188599 + + + + -5.630493 + + + + -6.111206 + + + + -4.669312 + + + + -3.227295 + + + + -1.304688 + + + + 0.618042 + + + + -0.824097 + + + + -1.304688 + + + + 0.137451 + + + + -0.343384 + + + + -0.343384 + + + + 3.501953 + + + + 3.501953 + + + + 4.463257 + + + + 6.385864 + + + + 7.347168 + + + + 8.308594 + + + + 11.192505 + + + + 15.518433 + + + + 10.711792 + + + + 10.231201 + + + + 8.789185 + + + + 9.269897 + + + + 6.866455 + + + + 5.424561 + + + + 4.943848 + + + + 4.463257 + + + + 4.943848 + + + + 4.943848 + + + + 4.943848 + + + + 3.501953 + + + + 3.982666 + + + + 4.943848 + + + + 4.943848 + + + + 3.982666 + + + + 3.982666 + + + + 1.579346 + + + + 3.501953 + + + + 5.424561 + + + + 4.463257 + + + + 7.827881 + + + + 12.153809 + + + + 7.827881 + + + + 7.827881 + + + + 6.866455 + + + + 6.385864 + + + + 5.905273 + + + + 7.827881 + + + + 5.424561 + + + + 10.231201 + + + + 12.153809 + + + + 20.324951 + + + + 21.766968 + + + + 23.208984 + + + + 18.402344 + + + + 17.921753 + + + + 15.037720 + + + + 12.153809 + + + + 15.037720 + + + + 16.960449 + + + + 19.844360 + + + + 27.534912 + + + + 28.976929 + + + + 32.822266 + + + + 33.783447 + + + + 35.225464 + + + + 35.225464 + + + + 28.015503 + + + + 21.766968 + + + + 24.651001 + + + + 26.573608 + + + + 30.418823 + + + + 30.899536 + + + + 28.496216 + + + + 16.479736 + + + + 16.479736 + + + + 19.363770 + + + + 24.170288 + + + + 32.822266 + + + + 33.783447 + + + + 36.667480 + + + + 37.148071 + + + + 37.148071 + + + + 36.667480 + + + + 38.109375 + + + + 37.148071 + + + + 37.148071 + + + + 37.148071 + + + + 36.667480 + + + + 36.667480 + + + + 36.667480 + + + + 41.954712 + + + + 42.435425 + + + + 40.993408 + + + + 40.032104 + + + + 39.551270 + + + + 38.590088 + + + + 37.628662 + + + + 36.667480 + + + + 35.706055 + + + + 34.744873 + + + + 34.264160 + + + + 34.744873 + + + + 33.783447 + + + + 32.341553 + + + + 32.341553 + + + + 31.860718 + + + + 32.341553 + + + + 32.341553 + + + + 28.976929 + + + + 27.534912 + + + + 29.457520 + + + + 30.418823 + + + + 30.899536 + + + + 30.418823 + + + + 28.976929 + + + + 28.496216 + + + + 29.457520 + + + + 28.976929 + + + + 28.015503 + + + + + + ACTIVE LOG #11 +13 + + + 50.125977 + + + + 46.280640 + + + + 41.954712 + + + + 44.838623 + + + + 45.799927 + + + + 45.799927 + + + + 47.241821 + + + + 44.838623 + + + + 43.396606 + + + + 43.877319 + + + + 43.877319 + + + + 42.916016 + + + + 45.319214 + + + + 42.916016 + + + + 43.396606 + + + + 44.838623 + + + + 43.396606 + + + + 32.341553 + + + + 29.457520 + + + + 26.573608 + + + + 24.170288 + + + + 22.728271 + + + + 22.247559 + + + + 22.247559 + + + + 19.363770 + + + + 21.286377 + + + + 18.402344 + + + + 20.805664 + + + + 22.247559 + + + + 23.689575 + + + + 21.766968 + + + + 18.402344 + + + + 15.518433 + + + + 15.518433 + + + + 13.595825 + + + + 11.192505 + + + + 12.153809 + + + + 13.595825 + + + + 10.231201 + + + + 11.192505 + + + + 9.750610 + + + + 8.789185 + + + + 9.269897 + + + + 8.789185 + + + + 6.866455 + + + + 6.866455 + + + + 7.347168 + + + + 8.789185 + + + + 16.960449 + + + + 18.883057 + + + + 19.844360 + + + + 14.557007 + + + + 13.115112 + + + + 10.711792 + + + + 8.308594 + + + + 8.308594 + + + + 7.827881 + + + + 6.866455 + + + + 5.905273 + + + + 13.115112 + + + + 9.750610 + + + + 9.269897 + + + + 7.347168 + + + + 8.308594 + + + + 9.750610 + + + + 10.231201 + + + + 7.827881 + + + + 7.347168 + + + + 6.385864 + + + + 7.347168 + + + + 7.347168 + + + + 11.673218 + + + + 12.634399 + + + + 15.518433 + + + + 15.518433 + + + + 14.557007 + + + + 14.557007 + + + + 10.231201 + + + + 8.308594 + + + + 3.501953 + + + + 8.789185 + + + + 8.789185 + + + + 9.269897 + + + + 8.308594 + + + + 13.115112 + + + + 12.153809 + + + + 19.844360 + + + + 17.921753 + + + + 18.883057 + + + + 18.883057 + + + + 19.363770 + + + + 18.883057 + + + + 19.844360 + + + + 19.844360 + + + + 19.363770 + + + + 19.363770 + + + + 19.363770 + + + + 17.441162 + + + + 19.844360 + + + + 18.402344 + + + + 18.402344 + + + + 18.402344 + + + + 16.960449 + + + + 15.518433 + + + + 11.192505 + + + + 11.192505 + + + + + + ACTIVE LOG #12 +14 + + + 39.551270 + + + + 43.396606 + + + + + diff --git a/reference/track/tpo-sample2.tpo b/reference/track/tpo-sample2.tpo new file mode 100644 index 0000000000000000000000000000000000000000..ab7556c2884125ae23f8d3a84375b30706545a33 GIT binary patch literal 5933 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 literal 0 HcmV?d00001 diff --git a/reference/track/trackDMm.ktf b/reference/track/trackDMm.ktf new file mode 100644 index 000000000..f2b8c83d2 --- /dev/null +++ b/reference/track/trackDMm.ktf @@ -0,0 +1,179 @@ +//Kartex TrackFil skapad av Kartex 5.0 +&KTF 2.0,sweref 99 lat long,1 +%,19,N56°9.098' E13°45.642',54.00,2006-03-07 15:58:36,,,$ +%,20,N56°9.101' E13°45.642',47.00,2006-03-07 15:58:38,,,$ +%,21,N56°9.080' E13°45.630',47.00,2006-03-07 15:59:00,,,$ +%,22,N56°9.056' E13°45.619',46.00,2006-03-07 15:59:29,,,$ +%,23,N56°9.021' E13°45.598',46.00,2006-03-07 16:00:12,,,$ +%,24,N56°8.984' E13°45.579',47.00,2006-03-07 16:00:58,,,$ +%,25,N56°8.953' E13°45.561',48.00,2006-03-07 16:01:38,,,$ +%,26,N56°8.930' E13°45.547',47.00,2006-03-07 16:02:06,,,$ +%,27,N56°8.913' E13°45.543',47.00,2006-03-07 16:02:27,,,$ +%,28,N56°8.882' E13°45.531',46.00,2006-03-07 16:03:04,,,$ +%,29,N56°8.856' E13°45.529',46.00,2006-03-07 16:03:35,,,$ +%,30,N56°8.838' E13°45.526',44.00,2006-03-07 16:04:02,,,$ +%,31,N56°8.838' E13°45.526',45.00,2006-03-07 16:04:11,,,$ +%,32,N56°8.837' E13°45.518',45.00,2006-03-07 16:04:16,,,$ +%,33,N56°8.827' E13°45.490',46.00,2006-03-07 16:04:39,,,$ +%,34,N56°8.820' E13°45.465',48.00,2006-03-07 16:04:59,,,$ +%,35,N56°8.797' E13°45.444',47.00,2006-03-07 16:05:33,,,$ +%,36,N56°8.773' E13°45.431',45.00,2006-03-07 16:06:04,,,$ +%,37,N56°8.742' E13°45.414',43.00,2006-03-07 16:06:46,,,$ +%,38,N56°8.727' E13°45.414',45.00,2006-03-07 16:07:07,,,$ +%,39,N56°8.721' E13°45.437',45.00,2006-03-07 16:07:26,,,$ +%,40,N56°8.718' E13°45.447',44.00,2006-03-07 16:07:35,,,$ +%,41,N56°8.697' E13°45.451',45.00,2006-03-07 16:08:03,,,$ +%,42,N56°8.680' E13°45.468',44.00,2006-03-07 16:08:28,,,$ +%,43,N56°8.667' E13°45.520',41.00,2006-03-07 16:09:08,,,$ +%,44,N56°8.671' E13°45.540',42.00,2006-03-07 16:09:23,,,$ +%,45,N56°8.667' E13°45.553',43.00,2006-03-07 16:09:35,,,$ +%,46,N56°8.648' E13°45.549',44.00,2006-03-07 16:09:58,,,$ +%,47,N56°8.612' E13°45.541',45.00,2006-03-07 16:10:40,,,$ +%,48,N56°8.587' E13°45.513',46.00,2006-03-07 16:11:14,,,$ +%,49,N56°8.565' E13°45.481',48.00,2006-03-07 16:11:49,,,$ +%,50,N56°8.531' E13°45.453',48.00,2006-03-07 16:12:34,,,$ +%,51,N56°8.529' E13°45.453',48.00,2006-03-07 16:12:53,,,$ +%,52,N56°8.528' E13°45.450',48.00,2006-03-07 16:13:21,,,$ +%,53,N56°8.505' E13°45.436',50.00,2006-03-07 16:13:51,,,$ +%,54,N56°8.487' E13°45.427',49.00,2006-03-07 16:14:17,,,$ +%,55,N56°8.462' E13°45.405',46.00,2006-03-07 16:14:51,,,$ +%,56,N56°8.444' E13°45.381',46.00,2006-03-07 16:15:19,,,$ +%,57,N56°8.428' E13°45.361',46.00,2006-03-07 16:15:54,,,$ +%,58,N56°8.424' E13°45.356',45.00,2006-03-07 16:16:13,,,$ +%,59,N56°8.413' E13°45.341',44.00,2006-03-07 16:16:33,,,$ +%,60,N56°8.385' E13°45.312',43.00,2006-03-07 16:17:11,,,$ +%,61,N56°8.373' E13°45.292',44.00,2006-03-07 16:17:35,,,$ +%,62,N56°8.370' E13°45.288',44.00,2006-03-07 16:17:41,,,$ +%,63,N56°8.340' E13°45.307',43.00,2006-03-07 16:18:19,,,$ +%,64,N56°8.326' E13°45.310',43.00,2006-03-07 16:18:35,,,$ +%,65,N56°8.323' E13°45.303',44.00,2006-03-07 16:18:41,,,$ +%,66,N56°8.317' E13°45.225',43.00,2006-03-07 16:19:36,,,$ +%,67,N56°8.314' E13°45.189',44.00,2006-03-07 16:20:01,,,$ +%,68,N56°8.300' E13°45.166',44.00,2006-03-07 16:20:25,,,$ +%,69,N56°8.264' E13°45.163',44.00,2006-03-07 16:21:11,,,$ +%,70,N56°8.224' E13°45.190',42.00,2006-03-07 16:22:05,,,$ +%,71,N56°8.210' E13°45.220',43.00,2006-03-07 16:22:34,,,$ +%,72,N56°8.198' E13°45.249',44.00,2006-03-07 16:23:01,,,$ +%,73,N56°8.182' E13°45.298',44.00,2006-03-07 16:23:42,,,$ +%,74,N56°8.178' E13°45.311',44.00,2006-03-07 16:24:03,,,$ +%,75,N56°8.178' E13°45.314',44.00,2006-03-07 16:24:05,,,$ +%,76,N56°8.173' E13°45.317',44.00,2006-03-07 16:24:11,,,$ +%,77,N56°8.146' E13°45.298',44.00,2006-03-07 16:24:48,,,$ +%,78,N56°8.121' E13°45.279',43.00,2006-03-07 16:25:22,,,$ +%,79,N56°8.097' E13°45.256',44.00,2006-03-07 16:26:03,,,$ +%,80,N56°8.086' E13°45.244',45.00,2006-03-07 16:26:35,,,$ +%,81,N56°8.080' E13°45.235',44.00,2006-03-07 16:26:55,,,$ +%,82,N56°8.050' E13°45.191',44.00,2006-03-07 16:27:42,,,$ +%,83,N56°8.025' E13°45.141',44.00,2006-03-07 16:28:30,,,$ +%,84,N56°8.022' E13°45.135',47.00,2006-03-07 16:28:55,,,$ +%,85,N56°8.014' E13°45.117',48.00,2006-03-07 16:29:40,,,$ +%,86,N56°7.995' E13°45.066',47.00,2006-03-07 16:30:23,,,$ +%,87,N56°7.976' E13°45.019',47.00,2006-03-07 16:31:04,,,$ +%,88,N56°7.958' E13°44.971',46.00,2006-03-07 16:31:45,,,$ +%,89,N56°7.952' E13°44.938',43.00,2006-03-07 16:32:13,,,$ +%,90,N56°7.950' E13°44.931',43.00,2006-03-07 16:32:27,,,$ +%,91,N56°7.950' E13°44.930',43.00,2006-03-07 16:32:29,,,$ +%,92,N56°7.923' E13°44.902',44.00,2006-03-07 16:33:09,,,$ +%,93,N56°7.913' E13°44.895',45.00,2006-03-07 16:33:31,,,$ +%,94,N56°7.882' E13°44.866',46.00,2006-03-07 16:34:15,,,$ +%,95,N56°7.866' E13°44.850',47.00,2006-03-07 16:34:44,,,$ +%,96,N56°7.840' E13°44.819',44.00,2006-03-07 16:35:22,,,$ +%,97,N56°7.810' E13°44.783',43.00,2006-03-07 16:36:09,,,$ +%,98,N56°7.781' E13°44.750',43.00,2006-03-07 16:36:52,,,$ +%,99,N56°7.754' E13°44.720',44.00,2006-03-07 16:37:30,,,$ +%,100,N56°7.723' E13°44.687',43.00,2006-03-07 16:38:15,,,$ +%,101,N56°7.687' E13°44.647',43.00,2006-03-07 16:39:06,,,$ +%,102,N56°7.656' E13°44.613',44.00,2006-03-07 16:39:52,,,$ +%,103,N56°7.636' E13°44.591',44.00,2006-03-07 16:40:24,,,$ +%,104,N56°7.607' E13°44.566',44.00,2006-03-07 16:41:05,,,$ +%,105,N56°7.588' E13°44.550',44.00,2006-03-07 16:41:34,,,$ +%,106,N56°7.574' E13°44.539',47.00,2006-03-07 16:42:03,,,$ +%,107,N56°7.567' E13°44.535',46.00,2006-03-07 16:42:15,,,$ +%,108,N56°7.565' E13°44.532',46.00,2006-03-07 16:42:37,,,$ +%,109,N56°7.558' E13°44.527',46.00,2006-03-07 16:42:58,,,$ +%,110,N56°7.547' E13°44.519',46.00,2006-03-07 16:43:16,,,$ +%,111,N56°7.517' E13°44.504',47.00,2006-03-07 16:43:54,,,$ +%,112,N56°7.486' E13°44.488',46.00,2006-03-07 16:44:36,,,$ +%,113,N56°7.466' E13°44.477',44.00,2006-03-07 16:45:04,,,$ +%,114,N56°7.440' E13°44.460',44.00,2006-03-07 16:45:38,,,$ +%,115,N56°7.409' E13°44.443',44.00,2006-03-07 16:46:20,,,$ +%,116,N56°7.376' E13°44.433',46.00,2006-03-07 16:47:02,,,$ +%,117,N56°7.345' E13°44.427',49.00,2006-03-07 16:47:40,,,$ +%,118,N56°7.309' E13°44.417',50.00,2006-03-07 16:48:25,,,$ +%,119,N56°7.275' E13°44.405',51.00,2006-03-07 16:49:07,,,$ +%,120,N56°7.268' E13°44.399',51.00,2006-03-07 16:49:31,,,$ +%,121,N56°7.262' E13°44.397',52.00,2006-03-07 16:49:52,,,$ +%,122,N56°7.259' E13°44.397',52.00,2006-03-07 16:50:18,,,$ +%,123,N56°7.237' E13°44.387',52.00,2006-03-07 16:50:49,,,$ +%,124,N56°7.216' E13°44.376',52.00,2006-03-07 16:51:23,,,$ +%,125,N56°7.204' E13°44.375',53.00,2006-03-07 16:51:56,,,$ +%,126,N56°7.188' E13°44.370',53.00,2006-03-07 16:52:26,,,$ +%,127,N56°7.188' E13°44.370',52.00,2006-03-07 16:52:35,,,$ +%,128,N56°7.154' E13°44.374',52.00,2006-03-07 16:53:17,,,$ +%,129,N56°7.119' E13°44.380',51.00,2006-03-07 16:54:00,,,$ +%,130,N56°7.083' E13°44.402',51.00,2006-03-07 16:54:47,,,$ +%,131,N56°7.056' E13°44.423',50.00,2006-03-07 16:55:24,,,$ +%,132,N56°7.024' E13°44.433',49.00,2006-03-07 16:56:05,,,$ +%,133,N56°6.983' E13°44.436',50.00,2006-03-07 16:56:54,,,$ +%,134,N56°6.957' E13°44.437',52.00,2006-03-07 16:57:27,,,$ +%,135,N56°6.922' E13°44.438',52.00,2006-03-07 16:58:11,,,$ +%,136,N56°6.902' E13°44.392',48.00,2006-03-07 16:58:52,,,$ +%,137,N56°6.898' E13°44.340',46.00,2006-03-07 16:59:27,,,$ +%,138,N56°6.901' E13°44.294',47.00,2006-03-07 16:59:57,,,$ +%,139,N56°6.904' E13°44.253',46.00,2006-03-07 17:00:26,,,$ +%,140,N56°6.922' E13°44.204',45.00,2006-03-07 17:01:07,,,$ +%,141,N56°6.950' E13°44.182',44.00,2006-03-07 17:01:45,,,$ +%,142,N56°6.979' E13°44.161',45.00,2006-03-07 17:02:25,,,$ +%,143,N56°6.998' E13°44.152',44.00,2006-03-07 17:02:50,,,$ +%,144,N56°7.033' E13°44.139',44.00,2006-03-07 17:03:32,,,$ +%,145,N56°7.069' E13°44.134',45.00,2006-03-07 17:04:17,,,$ +%,146,N56°7.104' E13°44.125',45.00,2006-03-07 17:04:59,,,$ +%,147,N56°7.112' E13°44.112',45.00,2006-03-07 17:05:11,,,$ +%,148,N56°7.136' E13°44.110',44.00,2006-03-07 17:05:43,,,$ +%,149,N56°7.149' E13°44.107',44.00,2006-03-07 17:05:58,,,$ +%,150,N56°7.156' E13°44.085',44.00,2006-03-07 17:06:16,,,$ +%,151,N56°7.175' E13°44.092',44.00,2006-03-07 17:06:41,,,$ +%,152,N56°7.190' E13°44.060',43.00,2006-03-07 17:07:15,,,$ +%,153,N56°7.204' E13°44.042',43.00,2006-03-07 17:07:38,,,$ +%,154,N56°7.217' E13°44.033',43.00,2006-03-07 17:07:59,,,$ +%,155,N56°7.221' E13°44.031',43.00,2006-03-07 17:08:27,,,$ +%,156,N56°7.221' E13°44.031',43.00,2006-03-07 17:08:35,,,$ +%,157,N56°7.240' E13°43.996',41.00,2006-03-07 17:09:12,,,$ +%,158,N56°7.256' E13°43.963',41.00,2006-03-07 17:09:45,,,$ +%,159,N56°7.270' E13°43.933',40.00,2006-03-07 17:10:14,,,$ +%,160,N56°7.287' E13°43.895',40.00,2006-03-07 17:10:51,,,$ +%,161,N56°7.307' E13°43.850',41.00,2006-03-07 17:11:35,,,$ +%,162,N56°7.322' E13°43.806',41.00,2006-03-07 17:12:14,,,$ +%,163,N56°7.337' E13°43.770',40.00,2006-03-07 17:12:47,,,$ +%,164,N56°7.355' E13°43.729',39.00,2006-03-07 17:13:27,,,$ +%,165,N56°7.373' E13°43.685',40.00,2006-03-07 17:14:09,,,$ +%,166,N56°7.390' E13°43.646',41.00,2006-03-07 17:14:48,,,$ +%,167,N56°7.396' E13°43.632',41.00,2006-03-07 17:15:08,,,$ +%,168,N56°7.407' E13°43.612',41.00,2006-03-07 17:15:32,,,$ +%,169,N56°7.418' E13°43.583',40.00,2006-03-07 17:15:59,,,$ +%,170,N56°7.434' E13°43.552',40.00,2006-03-07 17:16:30,,,$ +%,171,N56°7.453' E13°43.515',39.00,2006-03-07 17:17:09,,,$ +%,172,N56°7.468' E13°43.485',40.00,2006-03-07 17:17:41,,,$ +%,173,N56°7.484' E13°43.447',39.00,2006-03-07 17:18:17,,,$ +%,174,N56°7.490' E13°43.425',38.00,2006-03-07 17:18:45,,,$ +%,175,N56°7.497' E13°43.407',38.00,2006-03-07 17:19:21,,,$ +%,176,N56°7.512' E13°43.371',38.00,2006-03-07 17:19:54,,,$ +%,177,N56°7.520' E13°43.354',38.00,2006-03-07 17:20:12,,,$ +%,178,N56°7.524' E13°43.339',38.00,2006-03-07 17:20:29,,,$ +%,179,N56°7.528' E13°43.350',39.00,2006-03-07 17:20:39,,,$ +%,180,N56°7.547' E13°43.359',40.00,2006-03-07 17:21:06,,,$ +%,181,N56°7.549' E13°43.360',40.00,2006-03-07 17:21:11,,,$ +%,182,N56°7.553' E13°43.359',40.00,2006-03-07 17:21:16,,,$ +%,183,N56°7.551' E13°43.342',41.00,2006-03-07 17:21:32,,,$ +%,184,N56°7.552' E13°43.328',41.00,2006-03-07 17:21:56,,,$ +%,185,N56°7.552' E13°43.323',42.00,2006-03-07 17:22:16,,,$ +%,186,N56°7.551' E13°43.323',41.00,2006-03-07 17:22:52,,,$ +%,187,N56°7.552' E13°43.317',41.00,2006-03-07 17:23:10,,,$ +%,188,N56°7.555' E13°43.318',41.00,2006-03-07 17:23:30,,,$ +%,189,N56°7.553' E13°43.318',41.00,2006-03-07 17:24:15,,,$ +%,190,N56°7.552' E13°43.330',38.00,2006-03-07 17:33:44,,,$ +%,191,N56°7.548' E13°43.333',38.00,2006-03-07 17:34:10,,,$ +%,192,N56°7.547' E13°43.335',40.00,2006-03-07 17:34:40,,,$ +%,193,N56°7.547' E13°43.332',40.00,2006-03-07 17:34:58,,,$ +%,194,N56°7.549' E13°43.339',41.00,2006-03-07 17:35:12,,,$ +%,195,N56°7.549' E13°43.339',40.00,2006-03-07 17:35:52,,,$ diff --git a/reference/track/trackDd.ktf b/reference/track/trackDd.ktf new file mode 100644 index 000000000..b1688f926 --- /dev/null +++ b/reference/track/trackDd.ktf @@ -0,0 +1,179 @@ +//Kartex TrackFil skapad av Kartex 5.0 +&KTF 2.0,sweref 99 lat long,0 +%,19,N56.151633° E13.760700°,54.00,2006-03-07 15:58:36,,,$ +%,20,N56.151683° E13.760700°,47.00,2006-03-07 15:58:38,,,$ +%,21,N56.151333° E13.760500°,47.00,2006-03-07 15:59:00,,,$ +%,22,N56.150933° E13.760317°,46.00,2006-03-07 15:59:29,,,$ +%,23,N56.150350° E13.759967°,46.00,2006-03-07 16:00:12,,,$ +%,24,N56.149733° E13.759650°,47.00,2006-03-07 16:00:58,,,$ +%,25,N56.149217° E13.759350°,48.00,2006-03-07 16:01:38,,,$ +%,26,N56.148833° E13.759117°,47.00,2006-03-07 16:02:06,,,$ +%,27,N56.148550° E13.759050°,47.00,2006-03-07 16:02:27,,,$ +%,28,N56.148033° E13.758850°,46.00,2006-03-07 16:03:04,,,$ +%,29,N56.147600° E13.758817°,46.00,2006-03-07 16:03:35,,,$ +%,30,N56.147300° E13.758767°,44.00,2006-03-07 16:04:02,,,$ +%,31,N56.147300° E13.758767°,45.00,2006-03-07 16:04:11,,,$ +%,32,N56.147283° E13.758633°,45.00,2006-03-07 16:04:16,,,$ +%,33,N56.147117° E13.758167°,46.00,2006-03-07 16:04:39,,,$ +%,34,N56.147000° E13.757750°,48.00,2006-03-07 16:04:59,,,$ +%,35,N56.146617° E13.757400°,47.00,2006-03-07 16:05:33,,,$ +%,36,N56.146217° E13.757183°,45.00,2006-03-07 16:06:04,,,$ +%,37,N56.145700° E13.756900°,43.00,2006-03-07 16:06:46,,,$ +%,38,N56.145450° E13.756900°,45.00,2006-03-07 16:07:07,,,$ +%,39,N56.145350° E13.757283°,45.00,2006-03-07 16:07:26,,,$ +%,40,N56.145300° E13.757450°,44.00,2006-03-07 16:07:35,,,$ +%,41,N56.144950° E13.757517°,45.00,2006-03-07 16:08:03,,,$ +%,42,N56.144667° E13.757800°,44.00,2006-03-07 16:08:28,,,$ +%,43,N56.144450° E13.758667°,41.00,2006-03-07 16:09:08,,,$ +%,44,N56.144517° E13.759000°,42.00,2006-03-07 16:09:23,,,$ +%,45,N56.144450° E13.759217°,43.00,2006-03-07 16:09:35,,,$ +%,46,N56.144133° E13.759150°,44.00,2006-03-07 16:09:58,,,$ +%,47,N56.143533° E13.759017°,45.00,2006-03-07 16:10:40,,,$ +%,48,N56.143117° E13.758550°,46.00,2006-03-07 16:11:14,,,$ +%,49,N56.142750° E13.758017°,48.00,2006-03-07 16:11:49,,,$ +%,50,N56.142183° E13.757550°,48.00,2006-03-07 16:12:34,,,$ +%,51,N56.142150° E13.757550°,48.00,2006-03-07 16:12:53,,,$ +%,52,N56.142133° E13.757500°,48.00,2006-03-07 16:13:21,,,$ +%,53,N56.141750° E13.757267°,50.00,2006-03-07 16:13:51,,,$ +%,54,N56.141450° E13.757117°,49.00,2006-03-07 16:14:17,,,$ +%,55,N56.141033° E13.756750°,46.00,2006-03-07 16:14:51,,,$ +%,56,N56.140733° E13.756350°,46.00,2006-03-07 16:15:19,,,$ +%,57,N56.140467° E13.756017°,46.00,2006-03-07 16:15:54,,,$ +%,58,N56.140400° E13.755933°,45.00,2006-03-07 16:16:13,,,$ +%,59,N56.140217° E13.755683°,44.00,2006-03-07 16:16:33,,,$ +%,60,N56.139750° E13.755200°,43.00,2006-03-07 16:17:11,,,$ +%,61,N56.139550° E13.754867°,44.00,2006-03-07 16:17:35,,,$ +%,62,N56.139500° E13.754800°,44.00,2006-03-07 16:17:41,,,$ +%,63,N56.139000° E13.755117°,43.00,2006-03-07 16:18:19,,,$ +%,64,N56.138767° E13.755167°,43.00,2006-03-07 16:18:35,,,$ +%,65,N56.138717° E13.755050°,44.00,2006-03-07 16:18:41,,,$ +%,66,N56.138617° E13.753750°,43.00,2006-03-07 16:19:36,,,$ +%,67,N56.138567° E13.753150°,44.00,2006-03-07 16:20:01,,,$ +%,68,N56.138333° E13.752767°,44.00,2006-03-07 16:20:25,,,$ +%,69,N56.137733° E13.752717°,44.00,2006-03-07 16:21:11,,,$ +%,70,N56.137067° E13.753167°,42.00,2006-03-07 16:22:05,,,$ +%,71,N56.136833° E13.753667°,43.00,2006-03-07 16:22:34,,,$ +%,72,N56.136633° E13.754150°,44.00,2006-03-07 16:23:01,,,$ +%,73,N56.136367° E13.754967°,44.00,2006-03-07 16:23:42,,,$ +%,74,N56.136300° E13.755183°,44.00,2006-03-07 16:24:03,,,$ +%,75,N56.136300° E13.755233°,44.00,2006-03-07 16:24:05,,,$ +%,76,N56.136217° E13.755283°,44.00,2006-03-07 16:24:11,,,$ +%,77,N56.135767° E13.754967°,44.00,2006-03-07 16:24:48,,,$ +%,78,N56.135350° E13.754650°,43.00,2006-03-07 16:25:22,,,$ +%,79,N56.134950° E13.754267°,44.00,2006-03-07 16:26:03,,,$ +%,80,N56.134767° E13.754067°,45.00,2006-03-07 16:26:35,,,$ +%,81,N56.134667° E13.753917°,44.00,2006-03-07 16:26:55,,,$ +%,82,N56.134167° E13.753183°,44.00,2006-03-07 16:27:42,,,$ +%,83,N56.133750° E13.752350°,44.00,2006-03-07 16:28:30,,,$ +%,84,N56.133700° E13.752250°,47.00,2006-03-07 16:28:55,,,$ +%,85,N56.133567° E13.751950°,48.00,2006-03-07 16:29:40,,,$ +%,86,N56.133250° E13.751100°,47.00,2006-03-07 16:30:23,,,$ +%,87,N56.132933° E13.750317°,47.00,2006-03-07 16:31:04,,,$ +%,88,N56.132633° E13.749517°,46.00,2006-03-07 16:31:45,,,$ +%,89,N56.132533° E13.748967°,43.00,2006-03-07 16:32:13,,,$ +%,90,N56.132500° E13.748850°,43.00,2006-03-07 16:32:27,,,$ +%,91,N56.132500° E13.748833°,43.00,2006-03-07 16:32:29,,,$ +%,92,N56.132050° E13.748367°,44.00,2006-03-07 16:33:09,,,$ +%,93,N56.131883° E13.748250°,45.00,2006-03-07 16:33:31,,,$ +%,94,N56.131367° E13.747767°,46.00,2006-03-07 16:34:15,,,$ +%,95,N56.131100° E13.747500°,47.00,2006-03-07 16:34:44,,,$ +%,96,N56.130667° E13.746983°,44.00,2006-03-07 16:35:22,,,$ +%,97,N56.130167° E13.746383°,43.00,2006-03-07 16:36:09,,,$ +%,98,N56.129683° E13.745833°,43.00,2006-03-07 16:36:52,,,$ +%,99,N56.129233° E13.745333°,44.00,2006-03-07 16:37:30,,,$ +%,100,N56.128717° E13.744783°,43.00,2006-03-07 16:38:15,,,$ +%,101,N56.128117° E13.744117°,43.00,2006-03-07 16:39:06,,,$ +%,102,N56.127600° E13.743550°,44.00,2006-03-07 16:39:52,,,$ +%,103,N56.127267° E13.743183°,44.00,2006-03-07 16:40:24,,,$ +%,104,N56.126783° E13.742767°,44.00,2006-03-07 16:41:05,,,$ +%,105,N56.126467° E13.742500°,44.00,2006-03-07 16:41:34,,,$ +%,106,N56.126233° E13.742317°,47.00,2006-03-07 16:42:03,,,$ +%,107,N56.126117° E13.742250°,46.00,2006-03-07 16:42:15,,,$ +%,108,N56.126083° E13.742200°,46.00,2006-03-07 16:42:37,,,$ +%,109,N56.125967° E13.742117°,46.00,2006-03-07 16:42:58,,,$ +%,110,N56.125783° E13.741983°,46.00,2006-03-07 16:43:16,,,$ +%,111,N56.125283° E13.741733°,47.00,2006-03-07 16:43:54,,,$ +%,112,N56.124767° E13.741467°,46.00,2006-03-07 16:44:36,,,$ +%,113,N56.124433° E13.741283°,44.00,2006-03-07 16:45:04,,,$ +%,114,N56.124000° E13.741000°,44.00,2006-03-07 16:45:38,,,$ +%,115,N56.123483° E13.740717°,44.00,2006-03-07 16:46:20,,,$ +%,116,N56.122933° E13.740550°,46.00,2006-03-07 16:47:02,,,$ +%,117,N56.122417° E13.740450°,49.00,2006-03-07 16:47:40,,,$ +%,118,N56.121817° E13.740283°,50.00,2006-03-07 16:48:25,,,$ +%,119,N56.121250° E13.740083°,51.00,2006-03-07 16:49:07,,,$ +%,120,N56.121133° E13.739983°,51.00,2006-03-07 16:49:31,,,$ +%,121,N56.121033° E13.739950°,52.00,2006-03-07 16:49:52,,,$ +%,122,N56.120983° E13.739950°,52.00,2006-03-07 16:50:18,,,$ +%,123,N56.120617° E13.739783°,52.00,2006-03-07 16:50:49,,,$ +%,124,N56.120267° E13.739600°,52.00,2006-03-07 16:51:23,,,$ +%,125,N56.120067° E13.739583°,53.00,2006-03-07 16:51:56,,,$ +%,126,N56.119800° E13.739500°,53.00,2006-03-07 16:52:26,,,$ +%,127,N56.119800° E13.739500°,52.00,2006-03-07 16:52:35,,,$ +%,128,N56.119233° E13.739567°,52.00,2006-03-07 16:53:17,,,$ +%,129,N56.118650° E13.739667°,51.00,2006-03-07 16:54:00,,,$ +%,130,N56.118050° E13.740033°,51.00,2006-03-07 16:54:47,,,$ +%,131,N56.117600° E13.740383°,50.00,2006-03-07 16:55:24,,,$ +%,132,N56.117067° E13.740550°,49.00,2006-03-07 16:56:05,,,$ +%,133,N56.116383° E13.740600°,50.00,2006-03-07 16:56:54,,,$ +%,134,N56.115950° E13.740617°,52.00,2006-03-07 16:57:27,,,$ +%,135,N56.115367° E13.740633°,52.00,2006-03-07 16:58:11,,,$ +%,136,N56.115033° E13.739867°,48.00,2006-03-07 16:58:52,,,$ +%,137,N56.114967° E13.739000°,46.00,2006-03-07 16:59:27,,,$ +%,138,N56.115017° E13.738233°,47.00,2006-03-07 16:59:57,,,$ +%,139,N56.115067° E13.737550°,46.00,2006-03-07 17:00:26,,,$ +%,140,N56.115367° E13.736733°,45.00,2006-03-07 17:01:07,,,$ +%,141,N56.115833° E13.736367°,44.00,2006-03-07 17:01:45,,,$ +%,142,N56.116317° E13.736017°,45.00,2006-03-07 17:02:25,,,$ +%,143,N56.116633° E13.735867°,44.00,2006-03-07 17:02:50,,,$ +%,144,N56.117217° E13.735650°,44.00,2006-03-07 17:03:32,,,$ +%,145,N56.117817° E13.735567°,45.00,2006-03-07 17:04:17,,,$ +%,146,N56.118400° E13.735417°,45.00,2006-03-07 17:04:59,,,$ +%,147,N56.118533° E13.735200°,45.00,2006-03-07 17:05:11,,,$ +%,148,N56.118933° E13.735167°,44.00,2006-03-07 17:05:43,,,$ +%,149,N56.119150° E13.735117°,44.00,2006-03-07 17:05:58,,,$ +%,150,N56.119267° E13.734750°,44.00,2006-03-07 17:06:16,,,$ +%,151,N56.119583° E13.734867°,44.00,2006-03-07 17:06:41,,,$ +%,152,N56.119833° E13.734333°,43.00,2006-03-07 17:07:15,,,$ +%,153,N56.120067° E13.734033°,43.00,2006-03-07 17:07:38,,,$ +%,154,N56.120283° E13.733883°,43.00,2006-03-07 17:07:59,,,$ +%,155,N56.120350° E13.733850°,43.00,2006-03-07 17:08:27,,,$ +%,156,N56.120350° E13.733850°,43.00,2006-03-07 17:08:35,,,$ +%,157,N56.120667° E13.733267°,41.00,2006-03-07 17:09:12,,,$ +%,158,N56.120933° E13.732717°,41.00,2006-03-07 17:09:45,,,$ +%,159,N56.121167° E13.732217°,40.00,2006-03-07 17:10:14,,,$ +%,160,N56.121450° E13.731583°,40.00,2006-03-07 17:10:51,,,$ +%,161,N56.121783° E13.730833°,41.00,2006-03-07 17:11:35,,,$ +%,162,N56.122033° E13.730100°,41.00,2006-03-07 17:12:14,,,$ +%,163,N56.122283° E13.729500°,40.00,2006-03-07 17:12:47,,,$ +%,164,N56.122583° E13.728817°,39.00,2006-03-07 17:13:27,,,$ +%,165,N56.122883° E13.728083°,40.00,2006-03-07 17:14:09,,,$ +%,166,N56.123167° E13.727433°,41.00,2006-03-07 17:14:48,,,$ +%,167,N56.123267° E13.727200°,41.00,2006-03-07 17:15:08,,,$ +%,168,N56.123450° E13.726867°,41.00,2006-03-07 17:15:32,,,$ +%,169,N56.123633° E13.726383°,40.00,2006-03-07 17:15:59,,,$ +%,170,N56.123900° E13.725867°,40.00,2006-03-07 17:16:30,,,$ +%,171,N56.124217° E13.725250°,39.00,2006-03-07 17:17:09,,,$ +%,172,N56.124467° E13.724750°,40.00,2006-03-07 17:17:41,,,$ +%,173,N56.124733° E13.724117°,39.00,2006-03-07 17:18:17,,,$ +%,174,N56.124833° E13.723750°,38.00,2006-03-07 17:18:45,,,$ +%,175,N56.124950° E13.723450°,38.00,2006-03-07 17:19:21,,,$ +%,176,N56.125200° E13.722850°,38.00,2006-03-07 17:19:54,,,$ +%,177,N56.125333° E13.722567°,38.00,2006-03-07 17:20:12,,,$ +%,178,N56.125400° E13.722317°,38.00,2006-03-07 17:20:29,,,$ +%,179,N56.125467° E13.722500°,39.00,2006-03-07 17:20:39,,,$ +%,180,N56.125783° E13.722650°,40.00,2006-03-07 17:21:06,,,$ +%,181,N56.125817° E13.722667°,40.00,2006-03-07 17:21:11,,,$ +%,182,N56.125883° E13.722650°,40.00,2006-03-07 17:21:16,,,$ +%,183,N56.125850° E13.722367°,41.00,2006-03-07 17:21:32,,,$ +%,184,N56.125867° E13.722133°,41.00,2006-03-07 17:21:56,,,$ +%,185,N56.125867° E13.722050°,42.00,2006-03-07 17:22:16,,,$ +%,186,N56.125850° E13.722050°,41.00,2006-03-07 17:22:52,,,$ +%,187,N56.125867° E13.721950°,41.00,2006-03-07 17:23:10,,,$ +%,188,N56.125917° E13.721967°,41.00,2006-03-07 17:23:30,,,$ +%,189,N56.125883° E13.721967°,41.00,2006-03-07 17:24:15,,,$ +%,190,N56.125867° E13.722167°,38.00,2006-03-07 17:33:44,,,$ +%,191,N56.125800° E13.722217°,38.00,2006-03-07 17:34:10,,,$ +%,192,N56.125783° E13.722250°,40.00,2006-03-07 17:34:40,,,$ +%,193,N56.125783° E13.722200°,40.00,2006-03-07 17:34:58,,,$ +%,194,N56.125817° E13.722317°,41.00,2006-03-07 17:35:12,,,$ +%,195,N56.125817° E13.722317°,40.00,2006-03-07 17:35:52,,,$ diff --git a/reference/track/trackfilter-sdistance.gpx b/reference/track/trackfilter-sdistance.gpx new file mode 100644 index 000000000..0e963349e --- /dev/null +++ b/reference/track/trackfilter-sdistance.gpx @@ -0,0 +1,366 @@ + + + + + + LOG-20020525-20020525 + + + 1.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + + + 20020525 + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 6.000000 + + + + + + 20020525 + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + + + 20020525 + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020526 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020527 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/trackfilter-sdistance2.gpx b/reference/track/trackfilter-sdistance2.gpx new file mode 100644 index 000000000..e22b66086 --- /dev/null +++ b/reference/track/trackfilter-sdistance2.gpx @@ -0,0 +1,281 @@ + + + + + + 20020525 + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020525 + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 2.000000 + + + + 1.000000 + + + + 1.000000 + + + + 0.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 2.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 1.000000 + + + + 0.000000 + + + + 0.000000 + + + + 6.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + + 20020526 + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 7.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + 0.000000 + + + + + diff --git a/reference/track/trackfilter.gpx b/reference/track/trackfilter.gpx index 88190adb9..567b34cc6 100644 --- a/reference/track/trackfilter.gpx +++ b/reference/track/trackfilter.gpx @@ -1,267 +1,279 @@ - + - + + + LOG-20020525 - -1.000000 + + 1.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -2.000000 + + 2.000000 - -0.000000 + + 0.000000 - -1.000000 + + 1.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -2.000000 + + 2.000000 - -1.000000 + + 1.000000 - -1.000000 + + 1.000000 - -0.000000 + + 0.000000 - -2.000000 + + 2.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -6.000000 + + 6.000000 - -2.000000 + + 2.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -1.000000 + + 1.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -6.000000 + + 6.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + + + LOG-20020526 + + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -7.000000 + + 7.000000 - -0.000000 + + 0.000000 - -0.000000 + + + + LOG-20020527 + + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 - -0.000000 + + 0.000000 diff --git a/reference/track/tracks.gpssim b/reference/track/tracks.gpssim new file mode 100644 index 000000000..1c8d2a878 --- /dev/null +++ b/reference/track/tracks.gpssim @@ -0,0 +1,128 @@ +$FRSPD,0.04*65 +$FRWPT,3003.73100,N,09136.62100,W,1.0,250502,170621*63 +$FRSPD,1.24*66 +$FRWPT,3003.76700,N,09136.63400,W,0.0,250502,170955*69 +$FRSPD,6.70*60 +$FRWPT,3003.76200,N,09136.49600,W,0.0,250502,171200*6C +$FRSPD,7.43*61 +$FRWPT,3003.74000,N,09136.44300,W,0.0,250502,171248*68 +$FRSPD,7.39*6C +$FRWPT,3003.69200,N,09136.31700,W,0.0,250502,171441*6F +$FRSPD,14.61*53 +$FRWPT,3003.58700,N,09135.96400,W,0.0,250502,171716*64 +$FRSPD,43.13*54 +$FRWPT,3003.46800,N,09135.80100,W,0.0,250502,171746*63 +$FRSPD,35.48*5B +$FRWPT,3003.32300,N,09135.69400,W,0.0,250502,171820*66 +$FRSPD,25.45*57 +$FRWPT,3003.23300,N,09135.55700,W,0.0,250502,171901*68 +$FRSPD,19.37*5D +$FRWPT,3002.98400,N,09135.38500,W,0.0,250502,172046*6E +$FRSPD,12.72*57 +$FRWPT,3002.94100,N,09135.39300,W,0.0,250502,172110*62 +$FRSPD,27.18*5D +$FRWPT,3002.92800,N,09135.57600,W,0.0,250502,172151*65 +$FRSPD,38.06*5C +$FRWPT,3002.77400,N,09135.78700,W,0.0,250502,172235*6F +$FRSPD,26.63*50 +$FRWPT,3002.73100,N,09135.92300,W,0.0,250502,172308*61 +$FRSPD,0.38*6A +$FRWPT,3002.83800,N,09136.01600,W,0.0,250502,180423*68 +$FRSPD,2.60*65 +$FRWPT,3002.82000,N,09135.97800,W,2.0,250502,180604*66 +$FRSPD,3.97*6C +$FRWPT,3002.78600,N,09135.96800,W,0.0,250502,180706*65 +$FRSPD,2.95*6F +$FRWPT,3002.77200,N,09135.93700,W,1.0,250502,180818*65 +$FRSPD,3.68*6C +$FRWPT,3002.78200,N,09135.86400,W,0.0,250502,181020*6E +$FRSPD,4.21*66 +$FRWPT,3002.78100,N,09135.83000,W,0.0,250502,181109*66 +$FRSPD,5.13*66 +$FRWPT,3002.80700,N,09135.78000,W,0.0,250502,181218*60 +$FRSPD,4.02*67 +$FRWPT,3002.84700,N,09135.71200,W,0.0,250502,181422*60 +$FRSPD,5.14*61 +$FRWPT,3002.86800,N,09135.68600,W,2.0,250502,181504*66 +$FRSPD,4.47*66 +$FRWPT,3002.89500,N,09135.64500,W,1.0,250502,181614*6A +$FRSPD,4.46*67 +$FRWPT,3002.92100,N,09135.62800,W,1.0,250502,181701*6A +$FRSPD,4.26*61 +$FRWPT,3002.96100,N,09135.63100,W,0.0,250502,181807*6E +$FRSPD,3.94*6F +$FRWPT,3003.01900,N,09135.63900,W,2.0,250502,181951*61 +$FRSPD,4.21*66 +$FRWPT,3003.04700,N,09135.64700,W,0.0,250502,182039*65 +$FRSPD,4.67*64 +$FRWPT,3003.07400,N,09135.66200,W,0.0,250502,182124*6F +$FRSPD,4.50*60 +$FRWPT,3003.10800,N,09135.66200,W,0.0,250502,182217*66 +$FRSPD,3.39*68 +$FRWPT,3003.13300,N,09135.68000,W,0.0,250502,182318*6C +$FRSPD,4.26*61 +$FRWPT,3003.18100,N,09135.68100,W,0.0,250502,182437*6E +$FRSPD,3.71*64 +$FRWPT,3003.29200,N,09135.71200,W,6.0,250502,182813*68 +$FRSPD,2.40*67 +$FRWPT,3003.22400,N,09135.69600,W,2.0,250502,183136*63 +$FRSPD,2.97*6D +$FRWPT,3003.19100,N,09135.68700,W,0.0,250502,183256*69 +$FRSPD,3.52*65 +$FRWPT,3003.15800,N,09135.69000,W,0.0,250502,183402*6D +$FRSPD,1.91*68 +$FRWPT,3003.14700,N,09135.72600,W,0.0,250502,183603*6C +$FRSPD,4.33*65 +$FRWPT,3003.14900,N,09135.75800,W,0.0,250502,183648*64 +$FRSPD,4.77*65 +$FRWPT,3003.15900,N,09135.80700,W,1.0,250502,183752*6B +$FRSPD,5.10*65 +$FRWPT,3003.18800,N,09135.87100,W,0.0,250502,183918*67 +$FRSPD,3.64*60 +$FRWPT,3003.21700,N,09135.87800,W,0.0,250502,184015*68 +$FRSPD,2.35*65 +$FRWPT,3003.23800,N,09135.86600,W,6.0,250502,184125*6E +$FRSPD,2.60*65 +$FRWPT,3003.21700,N,09135.88500,W,0.0,250502,184237*68 +$FRSPD,2.21*60 +$FRWPT,3003.19200,N,09135.87500,W,0.0,250502,184401*6A +$FRSPD,1.94*6D +$FRWPT,3003.16900,N,09135.85100,W,0.0,250502,184553*6E +$FRSPD,3.89*63 +$FRWPT,3003.15400,N,09135.81600,W,0.0,250502,184654*67 +$FRSPD,4.31*67 +$FRWPT,3003.14000,N,09135.78600,W,0.0,250502,184742*62 +$FRSPD,4.67*64 +$FRWPT,3003.13500,N,09135.74100,W,0.0,250502,184841*67 +$FRSPD,3.42*64 +$FRWPT,3003.13300,N,09135.70100,W,0.0,250502,184952*66 +$FRSPD,3.18*6B +$FRWPT,3003.11300,N,09135.68200,W,0.0,250502,185049*6C +$FRSPD,4.32*64 +$FRWPT,3003.06300,N,09135.66400,W,0.0,250502,185214*68 +$FRSPD,5.05*61 +$FRWPT,3003.03400,N,09135.65400,W,0.0,250502,185256*6F +$FRSPD,4.01*64 +$FRWPT,3003.01100,N,09135.64600,W,0.0,250502,185338*62 +$FRSPD,5.12*67 +$FRWPT,3002.94600,N,09135.62300,W,0.0,250502,185511*66 +$FRSPD,4.14*60 +$FRWPT,3002.90700,N,09135.65500,W,0.0,250502,185632*60 +$FRSPD,4.59*69 +$FRWPT,3002.88500,N,09135.68500,W,0.0,250502,185724*60 +$FRSPD,4.66*65 +$FRWPT,3002.85000,N,09135.72700,W,7.0,250502,185840*6B +$FRSPD,5.64*66 +$FRWPT,3002.82400,N,09135.76000,W,0.0,250502,185928*63 +$FRSPD,5.27*61 +$FRWPT,3002.79800,N,09135.79600,W,0.0,250502,190022*65 +$FRSPD,5.00*64 +$FRWPT,3002.78400,N,09135.85900,W,0.0,250502,190141*60 +$FRSPD,4.56*66 +$FRWPT,3002.77400,N,09135.90800,W,0.0,250502,190248*60 +$FRSPD,3.37*66 +$FRWPT,3002.77900,N,09135.93800,W,0.0,250502,190343*64 +$FRSPD,3.45*63 +$FRWPT,3002.80700,N,09135.95700,W,0.0,250502,190449*66 +$FRSPD,2.98*62 +$FRWPT,3002.82800,N,09135.98000,W,0.0,250502,190557*6F diff --git a/reference/track/tracks.gpx b/reference/track/tracks.gpx index c606cd414..55dd18771 100644 --- a/reference/track/tracks.gpx +++ b/reference/track/tracks.gpx @@ -7,6 +7,7 @@ xmlns="http://www.topografix.com/GPX/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd"> +meridian 1.000000 diff --git a/reference/track/vitosmt_t.gpx b/reference/track/vitosmt_t.gpx index f692d17b2..afd743566 100644 --- a/reference/track/vitosmt_t.gpx +++ b/reference/track/vitosmt_t.gpx @@ -1,4 +1,4 @@ - + + diff --git a/reference/transform-rte.gpx b/reference/transform-rte.gpx new file mode 100644 index 000000000..f9995b15d --- /dev/null +++ b/reference/transform-rte.gpx @@ -0,0 +1,783 @@ + + + + + + + 44.586548 + + 5066 + 5066 + 5066 + Crossing +Crossing + + + 57.607200 + + 5067 + 5067 + 5067 + Dot +Intersection + + + 44.826904 + + 5096 + 5096 + 5096 + Dot +Dot + + + 50.594727 + + 5142 + 5142 + 5142 + Dot +Dot + + + 127.711200 + + 5156 + 5156 + 5156 + Dot +Intersection + + + 96.926400 + + 5224 + 5224 + 5224 + Dot +Intersection + + + 82.600800 + + 5229 + 5229 + 5229 + Dot +Intersection + + + 82.905600 + + 5237 + 5237 + 5237 + Dot +Intersection + + + 66.696655 + + 5254 + 5254 + 5254 + Dot +Dot + + + 74.627442 + + 5258 + 5258 + 5258 + Dot +Dot + + + 65.254761 + + 5264 + 5264 + 5264 + Dot +Dot + + + 77.419200 + + 526708 + 526708 + 526708 + Dot +Intersection + + + 74.676000 + + 526750 + 526750 + 526750 + Dot +Intersection + + + 78.713135 + + 527614 + 527614 + 527614 + Dot +Dot + + + 78.713135 + + 527631 + 527631 + 527631 + Dot +Dot + + + 68.275200 + + 5278 + 5278 + 5278 + Dot +Intersection + + + 64.008000 + + 5289 + 5289 + 5289 + Dot +Intersection + + + 52.997925 + + 5374FIRE + 5374FIRE + 5374FIRE + Dot +Dot + + + 56.388000 + + 5376 + 5376 + 5376 + Dot +Intersection + + + 56.388000 + + 6006 + 600698 + 600698 + Dot +Intersection + + + 46.028564 + + 6006BLUE + 6006BLUE + 6006BLUE + Dot +Dot + + + 37.616943 + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot +Dot + + + 56.388000 + + 6029 + 6029 + 6029 + Dot +Intersection + + + 50.292000 + + 6053 + 6053 + 6053 + Dot +Intersection + + + 25.603200 + + 6066 + 6066 + 6066 + Dot +Intersection + + + 34.442400 + + 6067 + 6067 + 6067 + Dot +Intersection + + + 30.480000 + + 6071 + 6071 + 6071 + Dot +Intersection + + + 15.240000 + + 6073 + 6073 + 6073 + Dot +Intersection + + + 37.795200 + + 6084 + 6084 + 6084 + Dot +Intersection + + + 64.008000 + + 6130 + 6130 + 6130 + Dot +Intersection + + + 64.008000 + + 6131 + 6131 + 6131 + Dot +Intersection + + + 62.788800 + + 6153 + 6153 + 6153 + Dot +Intersection + + + 55.473600 + + 6171 + 6171 + 6171 + Dot +Intersection + + + 62.484000 + + 6176 + 6176 + 6176 + Dot +Intersection + + + 62.179200 + + 6177 + 6177 + 6177 + Dot +Intersection + + + 69.799200 + + 6272 + 6272 + 6272 + Dot +Intersection + + + 73.152000 + + 6272 + 6272 + 6272 + Dot +Intersection + + + 70.104000 + + 6278 + 6278 + 6278 + Dot +Intersection + + + 57.564209 + + 6280 + 6280 + 6280 + Dot +Dot + + + 66.696655 + + 6283 + 6283 + 6283 + Dot +Dot + + + 72.945191 + + 6289 + 6289 + 6289 + Dot +Dot + + + 72.847200 + + 6297 + 6297 + 6297 + Dot +Intersection + + + 53.644800 + + 6328 + 6328 + 6328 + Dot +Intersection + + + 43.891200 + + 6354 + 6354 + 6354 + Dot +Intersection + + + 48.768000 + + 635722 + 635722 + 635722 + Dot +Intersection + + + 49.072800 + + 635783 + 635783 + 635783 + Dot +Intersection + + + 62.484000 + + 6373 + 6373 + 6373 + Dot +Intersection + + + 3.962400 + + 6634 + 6634 + 6634 + Dot +Intersection + + + 13.411200 + + 6979 + 6979 + 6979 + Dot +Intersection + + + 34.012085 + + 6997 + 6997 + 6997 + Dot +Dot + + + 87.782400 + + BEAR HILL + BEAR HILL TOWER + Bear Hill Tower + Tall Tower +Tower + + + 23.469600 + + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area +Parking + + + 43.384766 + + 6016 + Bike Loop Connector + Bike Loop Connector + Waypoint +Intersection + + + 89.916000 + + 5236BRIDGE + Bridge + Bridge + Bridge +Bridge + + + 55.473600 + + 5376BRIDGE + Bridge + Bridge + Bridge +Bridge + + + 52.730400 + + 6181CROSS + Crossing + Crossing + Crossing +Crossing + + + 45.110400 + + 6042CROSS + Crossing + Crossing + Crossing +Crossing + + + DARKHOLLPO + Dark Hollow Pond + Dark Hollow Pond + Fishing Area + + + 56.083200 + + 6121DEAD + Dead End + Dead End + Danger Area +Dead End + + + 117.043200 + + 5179DEAD + Dead End + Dead End + Danger Area +Dead End + + + 69.494400 + + 5299DEAD + Dead End + Dead End + Danger Area +Dead End + + + 56.997600 + + 5376DEAD + Dead End + Dead End + Danger Area +Dead End + + + 46.939200 + + 6353DEAD + Dead End + Dead End + Danger Area +Dead End + + + 61.264800 + + 6155DEAD + Dead End + Dead End + Danger Area +Dead End + + + 110.947200 + + GATE14 + Gate 14 + Gate 14 + Truck Stop +Road + + + 77.724000 + + GATE16 + Gate 16 + Gate 16 + Truck Stop +Road + + + 65.836800 + + GATE17 + Gate 17 + Gate 17 + Truck Stop +Road + + + 57.302400 + + GATE19 + Gate 19 + Gate 19 + Truck Stop +Road + + + 49.377600 + + GATE21 + Gate 21 + Gate 21 + Truck Stop +Road + + + 81.076800 + + GATE24 + Gate 24 + Gate 24 + Truck Stop +Road + + + 21.515015 + + GATE5 + Gate 5 + Gate 5 + Truck Stop +Truck Stop + + + 26.561890 + + GATE6 + Gate 6 + Gate 6 + Waypoint +Trail Head + + + 32.004000 + + 6077LOGS + Log Crossing + Log Crossing + Amusement Park +Obstacle + + + 119.809082 + + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint +Trail Head + + + 73.761600 + + 5267OBSTAC + Obstacle + Obstacle + Amusement Park +Obstacle + + + 45.307495 + + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel +Tunnel + + + 77.992066 + + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Summit +Summit + + + 67.970400 + + 5287WATER + Reservoir + Reservoir + Swimming Area +Reservoir + + + 81.076800 + + 5239ROAD + Road + Road + Truck Stop +Road + + + 67.360800 + + 5278ROAD + Road + Road + Truck Stop +Road + + + 53.949600 + + 5058ROAD + ROAD CROSSING + Road Crossing + Dot +Road Crossing + + + 69.799200 + + SHEEPFOLD + Sheepfold Parking Lot + Sheepfold Parking Lot + Parking Area +Parking + + + 64.008000 + + SOAPBOX + Soap Box Derby Track + Soap Box Derby Track + Cemetery +Intersection + + + 64.533692 + + 5376STREAM + Stream Crossing + Stream Crossing + Bridge +Bridge + + + 61.649902 + + 5144SUMMIT + Summit + Summit + Summit +Summit + + + 67.360800 + + 5150TANK + WATER TANK + Water Tank + Museum +Water Tank + + + diff --git a/reference/transform-wpt.gpx b/reference/transform-wpt.gpx new file mode 100644 index 000000000..7e01e9532 --- /dev/null +++ b/reference/transform-wpt.gpx @@ -0,0 +1,378 @@ + + + + + + 23.469600 + + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + + + 26.561890 + + GATE6 + Gate 6 + Gate 6 + Waypoint + + + 45.307495 + + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel + + + 37.616943 + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + + + 56.388000 + + 6006 + 600698 + 600698 + Dot + + + 46.028564 + + 6006BLUE + 6006BLUE + 6006BLUE + Dot + + + 44.826904 + + 5096 + 5096 + 5096 + Dot + + + 44.586548 + + 5066 + 5066 + 5066 + Crossing + + + 57.607200 + + 5067 + 5067 + 5067 + Dot + + + 53.949600 + + 5058ROAD + ROAD CROSSING + Road Crossing + Dot + + + 67.360800 + + 5150TANK + WATER TANK + Water Tank + Museum + + + 50.594727 + + 5142 + 5142 + 5142 + Dot + + + 61.649902 + + 5144SUMMIT + Summit + Summit + Summit + + + 127.711200 + + 5156 + 5156 + 5156 + Dot + + + 119.809082 + + 5148NANEPA + Nanepashemet Road Crossing + Nanepashemet Road Crossing + Waypoint + + + 74.627442 + + 5258 + 5258 + 5258 + Dot + + + 77.992066 + + 5252PURPLE + Purple Rock Hill + Purple Rock Hill + Summit + + + 78.713135 + + 527631 + 527631 + 527631 + Dot + + + 78.713135 + + 527614 + 527614 + 527614 + Dot + + + 73.761600 + + 5267OBSTAC + Obstacle + Obstacle + Amusement Park + + + 68.275200 + + 5278 + 5278 + 5278 + Dot + + + 64.008000 + + 5289 + 5289 + 5289 + Dot + + + 52.997925 + + 5374FIRE + 5374FIRE + 5374FIRE + Dot + + + 56.388000 + + 5376 + 5376 + 5376 + Dot + + + 64.533692 + + 5376STREAM + Stream Crossing + Stream Crossing + Bridge + + + 53.644800 + + 6328 + 6328 + 6328 + Dot + + + 48.768000 + + 635722 + 635722 + 635722 + Dot + + + 49.072800 + + 635783 + 635783 + 635783 + Dot + + + 62.484000 + + 6373 + 6373 + 6373 + Dot + + + 87.782400 + + BEAR HILL + BEAR HILL TOWER + Bear Hill Tower + Tall Tower + + + 72.945191 + + 6289 + 6289 + 6289 + Dot + + + 72.847200 + + 6297 + 6297 + 6297 + Dot + + + 66.696655 + + 6283 + 6283 + 6283 + Dot + + + 57.564209 + + 6280 + 6280 + 6280 + Dot + + + 62.179200 + + 6177 + 6177 + 6177 + Dot + + + 62.484000 + + 6176 + 6176 + 6176 + Dot + + + 62.788800 + + 6153 + 6153 + 6153 + Dot + + + 55.473600 + + 6171 + 6171 + 6171 + Dot + + + 64.008000 + + 6131 + 6131 + 6131 + Dot + + + 64.008000 + + 6130 + 6130 + 6130 + Dot + + + 56.388000 + + 6029 + 6029 + 6029 + Dot + + + 56.388000 + + 6006 + 600698 + 600698 + Dot + + + 37.616943 + + 6014MEADOW + 6014MEADOW + 6014MEADOW + Dot + + + 45.307495 + + PANTHRCAVE + Panther Cave + Panther Cave + Tunnel + + + 26.561890 + + GATE6 + Gate 6 + Gate 6 + Waypoint + + + 23.469600 + + BELLEVUE + BELLEVUE + Bellevue Parking Lot + Parking Area + + diff --git a/reference/unicsv.gpx b/reference/unicsv.gpx new file mode 100644 index 000000000..08f4ffedf --- /dev/null +++ b/reference/unicsv.gpx @@ -0,0 +1,55 @@ + + + + + + GCEBB + Mountain Bike Heaven by susy1313 + Mountain Bike Heaven by susy1313 + + + GC1A37 + The Troll by a182pilot & Family + The Troll by a182pilot & Family + + + GC1C2B + Dive Bomber by JoGPS & family + Dive Bomber by JoGPS & family + + + GC25A9 + FOSTER by JoGPS & Family + FOSTER by JoGPS & Family + + + GC2723 + Logan Lighthouse by JoGps & Family + Logan Lighthouse by JoGps & Family + + + GC2B71 + Ganier Cache by Susy1313 + Ganier Cache by Susy1313 + + + GC309F + Shy's Hill by FireFighterEng33 + Shy's Hill by FireFighterEng33 + + + GC317A + GittyUp by JoGPS / Warner Parks + GittyUp by JoGPS / Warner Parks + + + GC317D + Inlighting by JoGPS / Warner Parks + Inlighting by JoGPS / Warner Parks + + diff --git a/reference/vitosmt.gpx b/reference/vitosmt.gpx index 543661ff6..e2035e65d 100644 --- a/reference/vitosmt.gpx +++ b/reference/vitosmt.gpx @@ -1,4 +1,4 @@ - + oIJq%~Yq>I?WxOU=;o97ht8p{Fi>q@t?#Z>d3t!EFoAc?;Nt(^s zypwadDzD}SeAIs}w%9~}F$?6lH@rAwUn53(? z+twIPwolUaeE+r>#L2sc~d4g8TR6z<@v6h`|{CEo>9+t@m+l2<|G}IvHX|t5Wd2Ac5af6)i=TiQ9Sq!tT zS3f-3{8!3$6_oKiT8dSLw%WVh=SOZx(o@`SWeh*_*_W#s9%CQRcTtz?{w;SiQzN9y@m%D#ZbYG z_;-adB4lGn=Tah}W#R>iPZ&INp$cgc1puaMgic^2^{Yt*grIoy@U8lTVO z_&Q#|udG!A<|*c6oo~>134h4Ft*4Ynt&gFqep1GN;V!(AhjBe#$4~IRypiYdJl?|Z za2apo4|qP8^A`SsckwCS%lo+ch8T|XL9WlW?QaG5`P8>5s}nqc7jjn6WBCYI<~#T& zu5xC)pE{|=gNWB9@ z6JLKw{cy=)z2dLxhhIMx!*8a!^YGjQG2ET6ez?qeH)ELk;pJOmSk+Jc@RPo&mv2=+ z{4n>{#|Cp_y*JgPMsORwrKNLlG?(i0i}d!f+(`d9?kvdXjrzk78BXGbU&XMvkNV+` z_U;nzRlrmAlNa=gncTsD4KZgC=W?F!aSpe3&R*MF{cy>bYUU30!%uLPKdT?U$ukYP zgdgL?noBd!^E58wdv@BFLF$LcyBp*TS3lfLCNGXxKm5^g_4$AyY26W zO#k5@?dke^)DJJK@Q%;9^Kg#4$D!Mjv?k}tYNa!-4qxX!@RnY86`v!kbGRuVH|J7y z(voxCHy&_jXvh1%(Ze5fpW)iuoI&cRE9at=O2k-!XruApBL}b nKgT8MGu*-d7CT3#@*1^Q=}~t-&fI^p)J*Ob?iKdB(E0U0T7=qB literal 0 HcmV?d00001 diff --git a/reference/wbt-200.gpx b/reference/wbt-200.gpx new file mode 100644 index 000000000..eb3f0cf4e --- /dev/null +++ b/reference/wbt-200.gpx @@ -0,0 +1,790 @@ + + + + + + + WP0001 + + + WP0002 + + + WP0003 + + + WP0004 + + + WP0005 + + + WP0006 + + + WP0007 + + + WP0008 + + + WP0009 + + + WP0010 + + + WP0011 + + + WP0012 + + + WP0013 + + + WP0014 + + + WP0015 + + + WP0016 + + + WP0017 + + + WP0018 + + + WP0019 + + + WP0020 + + + WP0021 + + + WP0022 + + + WP0023 + + + WP0024 + + + WP0025 + + + WP0026 + + + WP0027 + + + WP0028 + + + WP0029 + + + WP0030 + + + WP0031 + + + WP0032 + + + WP0033 + + + WP0034 + + + WP0035 + + + WP0036 + + + WP0037 + + + WP0038 + + + WP0039 + + + WP0040 + + + WP0041 + + + WP0042 + + + WP0043 + + + WP0044 + + + WP0045 + + + WP0046 + + + WP0047 + + + WP0048 + + + WP0049 + + + WP0050 + + + WP0051 + + + WP0052 + + + WP0053 + + + WP0054 + + + WP0055 + + + WP0056 + + + WP0057 + + + WP0058 + + + WP0059 + + + WP0060 + + + WP0061 + + + WP0062 + + + WP0063 + + + WP0064 + + + WP0065 + + + WP0066 + + + WP0067 + + + WP0068 + + + WP0069 + + + WP0070 + + + WP0071 + + + WP0072 + + + WP0073 + + + WP0074 + + + WP0075 + + + WP0076 + + + WP0077 + + + WP0078 + + + WP0079 + + + WP0080 + + + WP0081 + + + WP0082 + + + WP0083 + + + WP0084 + + + WP0085 + + + WP0086 + + + WP0087 + + + WP0088 + + + WP0089 + + + WP0090 + + + WP0091 + + + WP0092 + + + WP0093 + + + WP0094 + + + WP0095 + + + WP0096 + + + WP0097 + + + WP0098 + + + WP0099 + + + WP0100 + + + WP0101 + + + WP0102 + + + WP0103 + + + WP0104 + + + WP0105 + + + WP0106 + + + WP0107 + + + WP0108 + + + WP0109 + + + WP0110 + + + WP0111 + + + WP0112 + + + WP0113 + + + WP0114 + + + WP0115 + + + WP0116 + + + WP0117 + + + WP0118 + + + WP0119 + + + WP0120 + + + WP0121 + + + WP0122 + + + WP0123 + + + WP0124 + + + WP0125 + + + WP0126 + + + WP0127 + + + WP0128 + + + WP0129 + + + WP0130 + + + WP0131 + + + WP0132 + + + WP0133 + + + WP0134 + + + WP0135 + + + WP0136 + + + WP0137 + + + WP0138 + + + WP0139 + + + WP0140 + + + WP0141 + + + WP0142 + + + WP0143 + + + WP0144 + + + WP0145 + + + WP0146 + + + WP0147 + + + WP0148 + + + WP0149 + + + WP0150 + + + WP0151 + + + WP0152 + + + WP0153 + + + WP0154 + + + WP0155 + + + WP0156 + + + WP0157 + + + WP0158 + + + WP0159 + + + WP0160 + + + WP0161 + + + WP0162 + + + WP0163 + + + WP0164 + + + WP0165 + + + WP0166 + + + WP0167 + + + WP0168 + + + WP0169 + + + WP0170 + + + WP0171 + + + WP0172 + + + WP0173 + + + WP0174 + + + WP0175 + + + WP0176 + + + WP0177 + + + WP0178 + + + WP0179 + + + WP0180 + + + WP0181 + + + WP0182 + + + WP0183 + + + WP0184 + + + WP0185 + + + WP0186 + + + WP0187 + + + WP0188 + + + WP0189 + + + WP0190 + + + WP0191 + + + WP0192 + + + WP0193 + + + WP0194 + + + WP0195 + + + WP0196 + + + WP0197 + + + WP0198 + + + WP0199 + + + WP0200 + + + WP0201 + + + WP0202 + + + WP0203 + + + WP0204 + + + WP0205 + + + WP0206 + + + WP0207 + + + WP0208 + + + WP0209 + + + WP0210 + + + WP0211 + + + WP0212 + + + WP0213 + + + WP0214 + + + WP0215 + + + WP0216 + + + WP0217 + + + WP0218 + + + WP0219 + + + WP0220 + + + WP0221 + + + WP0222 + + + WP0223 + + + WP0224 + + + WP0225 + + + WP0226 + + + WP0227 + + + WP0228 + + + WP0229 + + + WP0230 + + + WP0231 + + + WP0232 + + + WP0233 + + + WP0234 + + + WP0235 + + + WP0236 + + + WP0237 + + + WP0238 + + + WP0239 + + + WP0240 + + + WP0241 + + + WP0242 + + + WP0243 + + + WP0244 + + + WP0245 + + + WP0246 + + + WP0247 + + + WP0248 + + + WP0249 + + + WP0250 + + + WP0251 + + + WP0252 + + + WP0253 + + + WP0254 + + + WP0255 + + + WP0256 + + + WP0257 + + + WP0258 + + + WP0259 + + + + diff --git a/reference/wfff.gpu b/reference/wfff.gpu new file mode 100644 index 000000000..dec2b1836 --- /dev/null +++ b/reference/wfff.gpu @@ -0,0 +1 @@ +WitoldM 4529.388N 07541.190W 0000000m 001217AD3124/AP/WEP On/Ch 11/- a diff --git a/reference/wfff.xml b/reference/wfff.xml new file mode 100644 index 000000000..fc70b56d2 --- /dev/null +++ b/reference/wfff.xml @@ -0,0 +1,17 @@ + + + On + 001217AD3124 + WitoldM + AP + 0 + -77 + -85 + 11 + 2006-03-11T09:07:46-05:00 + 2006-03-11T09:07:52-05:00 + 14.2 + 45.489801666666672 + -75.686505 + + diff --git a/reverse_route.c b/reverse_route.c index 5ba3a7e32..5636cf6fa 100644 --- a/reverse_route.c +++ b/reverse_route.c @@ -18,14 +18,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -#include #include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED #define MYNAME "Route reversal filter" static arglist_t reverse_route_args[] = { - {0, 0, 0, 0, 0} + ARG_TERMINATOR }; void @@ -65,3 +67,4 @@ filter_vecs_t reverse_route_vecs = { NULL, reverse_route_args }; +#endif diff --git a/rgbcolors.c b/rgbcolors.c new file mode 100644 index 000000000..bfbe0f035 --- /dev/null +++ b/rgbcolors.c @@ -0,0 +1,248 @@ +/* + Color utilities. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +/* + * Colors derived from http://www.w3.org/TR/SVG/types.html#ColorKeywords + * which is also referenced in the CSS3 spec from w3.org as being the + * same colors supported by X11. + */ + +static struct { + char *cn; + unsigned char r; + unsigned char g; + unsigned char b; +} color_table[] = { + {"aliceblue", 240, 248, 255}, + {"antiquewhite", 250, 235, 215}, + {"aqua", 0, 255, 255}, + {"aquamarine", 127, 255, 212}, + {"azure", 240, 255, 255}, + {"beige", 245, 245, 220}, + {"bisque", 255, 228, 196}, + {"black", 0, 0, 0}, + {"blanchedalmond", 255, 235, 205}, + {"blue", 0, 0, 255}, + {"blueviolet", 138, 43, 226}, + {"brown", 165, 42, 42}, + {"burlywood", 222, 184, 135}, + {"cadetblue", 95, 158, 160}, + {"chartreuse", 127, 255, 0}, + {"chocolate", 210, 105, 30}, + {"coral", 255, 127, 80}, + {"cornflowerblue", 100, 149, 237}, + {"cornsilk", 255, 248, 220}, + {"crimson", 220, 20, 60}, + {"cyan", 0, 255, 255}, + {"darkblue", 0, 0, 139}, + {"darkcyan", 0, 139, 139}, + {"darkgoldenrod", 184, 134, 11}, + {"darkgray", 169, 169, 169}, + {"darkgreen", 0, 100, 0}, + {"darkgrey", 169, 169, 169}, + {"darkkhaki", 189, 183, 107}, + {"darkmagenta", 139, 0, 139}, + {"darkolivegreen", 85, 107, 47}, + {"darkorange", 255, 140, 0}, + {"darkorchid", 153, 50, 204}, + {"darkred", 139, 0, 0}, + {"darksalmon", 233, 150, 122}, + {"darkseagreen", 143, 188, 143}, + {"darkslateblue", 72, 61, 139}, + {"darkslategray", 47, 79, 79}, + {"darkslategrey", 47, 79, 79}, + {"darkturquoise", 0, 206, 209}, + {"darkviolet", 148, 0, 211}, + {"deeppink", 255, 20, 147}, + {"deepskyblue", 0, 191, 255}, + {"dimgray", 105, 105, 105}, + {"dimgrey", 105, 105, 105}, + {"dodgerblue", 30, 144, 255}, + {"firebrick", 178, 34, 34}, + {"floralwhite", 255, 250, 240}, + {"forestgreen", 34, 139, 34}, + {"fuchsia", 255, 0, 255}, + {"gainsboro", 220, 220, 220}, + {"ghostwhite", 248, 248, 255}, + {"gold", 255, 215, 0}, + {"goldenrod", 218, 165, 32}, + {"gray", 128, 128, 128}, + {"grey", 128, 128, 128}, + {"green", 0, 128, 0}, + {"greenyellow", 173, 255, 47}, + {"honeydew", 240, 255, 240}, + {"hotpink", 255, 105, 180}, + {"indianred", 205, 92, 92}, + {"indigo", 75, 0, 130}, + {"ivory", 255, 255, 240}, + {"khaki", 240, 230, 140}, + {"lavender", 230, 230, 250}, + {"lavenderblush", 255, 240, 245}, + {"lawngreen", 124, 252, 0}, + {"lemonchiffon", 255, 250, 205}, + {"lightblue", 173, 216, 230}, + {"lightcoral", 240, 128, 128}, + {"lightcyan", 224, 255, 255}, + {"lightgoldenrodyellow", 250, 250, 210}, + {"lightgray", 211, 211, 211}, + {"lightgreen", 144, 238, 144}, + {"lightgrey", 211, 211, 211}, + {"lightpink", 255, 182, 193}, + {"lightsalmon", 255, 160, 122}, + {"lightseagreen", 32, 178, 170}, + {"lightskyblue", 135, 206, 250}, + {"lightslategray", 119, 136, 153}, + {"lightslategrey", 119, 136, 153}, + {"lightsteelblue", 176, 196, 222}, + {"lightyellow", 255, 255, 224}, + {"lime", 0, 255, 0}, + {"limegreen", 50, 205, 50}, + {"linen", 250, 240, 230}, + {"magenta", 255, 0, 255}, + {"maroon", 128, 0, 0}, + {"mediumaquamarine", 102, 205, 170}, + {"mediumblue", 0, 0, 205}, + {"mediumorchid", 186, 85, 211}, + {"mediumpurple", 147, 112, 219}, + {"mediumseagreen", 60, 179, 113}, + {"mediumslateblue", 123, 104, 238}, + {"mediumspringgreen", 0, 250, 154}, + {"mediumturquoise", 72, 209, 204}, + {"mediumvioletred", 199, 21, 133}, + {"midnightblue", 25, 25, 112}, + {"mintcream", 245, 255, 250}, + {"mistyrose", 255, 228, 225}, + {"moccasin", 255, 228, 181}, + {"navajowhite", 255, 222, 173}, + {"navy", 0, 0, 128}, + {"oldlace", 253, 245, 230}, + {"olive", 128, 128, 0}, + {"olivedrab", 107, 142, 35}, + {"orange", 255, 165, 0}, + {"orangered", 255, 69, 0}, + {"orchid", 218, 112, 214}, + {"palegoldenrod", 238, 232, 170}, + {"palegreen", 152, 251, 152}, + {"paleturquoise", 175, 238, 238}, + {"palevioletred", 219, 112, 147}, + {"papayawhip", 255, 239, 213}, + {"peachpuff", 255, 218, 185}, + {"peru", 205, 133, 63}, + {"pink", 255, 192, 203}, + {"plum", 221, 160, 221}, + {"powderblue", 176, 224, 230}, + {"purple", 128, 0, 128}, + {"red", 255, 0, 0}, + {"rosybrown", 188, 143, 143}, + {"royalblue", 65, 105, 225}, + {"saddlebrown", 139, 69, 19}, + {"salmon", 250, 128, 114}, + {"sandybrown", 244, 164, 96}, + {"seagreen", 46, 139, 87}, + {"seashell", 255, 245, 238}, + {"sienna", 160, 82, 45}, + {"silver", 192, 192, 192}, + {"skyblue", 135, 206, 235}, + {"slateblue", 106, 90, 205}, + {"slategray", 112, 128, 144}, + {"slategrey", 112, 128, 144}, + {"snow", 255, 250, 250}, + {"springgreen", 0, 255, 127}, + {"steelblue", 70, 130, 180}, + {"tan", 210, 180, 140}, + {"teal", 0, 128, 128}, + {"thistle", 216, 191, 216}, + {"tomato", 255, 99, 71}, + {"turquoise", 64, 224, 208}, + {"violet", 238, 130, 238}, + {"wheat", 245, 222, 179}, + {"white", 255, 255, 255}, + {"whitesmoke", 245, 245, 245}, + {"yellow", 255, 255, 0}, + {"yellowgreen", 154, 205, 50}, +}; + + +/* + * Functions for converting human-readable colors to BBGGRR value. + * Substantial optimization opportunities remain. + */ +static int HexDigit( char hex ) { + const char *Digits = "0123456789ABCDEF"; + const char *digits = "0123456789abcdef"; + char * ofs = strchr( digits, hex ); + if ( ofs ) { + return ofs-digits; + } + + ofs = strchr( Digits, hex ); + if ( ofs ) { + return ofs-Digits; + } + return 0; +} + +static int HexByte( char* hex ) { + int b = (HexDigit(hex[0])<<4)+HexDigit(hex[1]); + return b; +} + +/* + * Given an input of the form: + * # + * + * + * return the BBGGRR value for it. + */ + +int +color_to_bbggrr( char *opt_color ) +{ + int color_num; + unsigned int i; + char *ep; + + color_num = strtol(opt_color, &ep, 10); + + if (ep != opt_color) { + return color_num; + } + + if ( opt_color[0] == '#' ) { + color_num = (HexByte( opt_color+1 )) + // red + (HexByte( opt_color+3 )<<8) + // green + (HexByte( opt_color+5 )<<16); // blue + return color_num; + } + + for (i = 0; i < sizeof(color_table) / sizeof(color_table[0]); i++) { + if (0 == case_ignore_strcmp(opt_color, color_table[i].cn)) { + return (color_table[i].b << 16) + + (color_table[i].g << 8) + + color_table[i].r; + } + } + + fatal( "unrecognized color name %s\n", opt_color ); + return -1; +} diff --git a/route.c b/route.c index e1069f08d..39130834f 100644 --- a/route.c +++ b/route.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002-2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,12 +19,14 @@ #include #include "defs.h" +#include "grtcirc.h" static queue my_route_head; static queue my_track_head; static int rte_head_ct; static int rte_waypts; static int trk_head_ct; +static int trk_waypts; void route_init(void) @@ -46,6 +48,13 @@ route_count(void) return rte_head_ct; /* total # of routes */ } +unsigned int +track_waypt_count(void) +{ + /* totaly waypoint count -- all tracks */ + return trk_waypts; +} + unsigned int track_count(void) { @@ -58,80 +67,159 @@ route_head_alloc(void) route_head *rte_head; rte_head = (route_head *) xcalloc(sizeof (*rte_head), 1); QUEUE_INIT(&rte_head->Q); + QUEUE_INIT(&rte_head->waypoint_list); return rte_head; } +static void +any_route_free(route_head *rte) +{ + if ( rte->rte_name ) { + xfree(rte->rte_name); + } + if ( rte->rte_desc ) { + xfree(rte->rte_desc); + } + if ( rte->rte_url ) { + xfree(rte->rte_url); + } + waypt_flush(&rte->waypoint_list); + if ( rte->fs ) { + fs_chain_destroy( rte->fs ); + } + xfree(rte); +} + + +static void +any_route_add_head( route_head *rte, queue *head ) { + ENQUEUE_TAIL( head, &rte->Q ); +} + +static void +any_route_del_head( route_head *rte ) { + dequeue( &rte->Q ); + any_route_free( rte ); +} void route_add_head(route_head *rte) { - ENQUEUE_TAIL(&my_route_head, &rte->Q); - QUEUE_INIT(&rte->waypoint_list); + any_route_add_head( rte, &my_route_head ); rte_head_ct++; } void route_del_head(route_head *rte) { - dequeue( &rte->Q ); - route_free( rte ); + any_route_del_head( rte ); rte_head_ct--; } void track_add_head(route_head *rte) { - ENQUEUE_TAIL(&my_track_head, &rte->Q); - QUEUE_INIT(&rte->waypoint_list); + any_route_add_head( rte, &my_track_head ); trk_head_ct++; } void track_del_head(route_head *rte) { - dequeue( &rte->Q ); - route_free( rte ); + any_route_del_head( rte ); trk_head_ct--; } -void -route_add_wpt(route_head *rte, waypoint *wpt) +static +route_head * +common_route_by_name(queue *routes, const char *name) +{ + queue *elem, *tmp; + route_head *rte; + + QUEUE_FOR_EACH(routes, elem, tmp) { + rte = (route_head *) elem; + if (0 == strcmp(rte->rte_name, name)) { + return rte; + } + } + + return NULL; +} + +route_head * +route_find_route_by_name(const char *name) +{ + return common_route_by_name(&my_route_head, name); +} + +route_head * +route_find_track_by_name(const char *name) +{ + return common_route_by_name(&my_track_head, name); +} + +static void +any_route_add_wpt(route_head *rte, waypoint *wpt, int *ct, int synth ) { ENQUEUE_TAIL(&rte->waypoint_list, &wpt->Q); rte->rte_waypt_ct++; /* waypoints in this route */ - rte_waypts++; /* total waypoints in all routes */ - if (wpt->shortname == NULL) { + if ( ct ) { + (*ct)++; + } + if ( synth && !wpt->shortname ) { char tmpnam[10]; - snprintf(tmpnam, sizeof(tmpnam), "RPT%03d",rte_waypts); + snprintf(tmpnam, sizeof(tmpnam), "RPT%03d",*ct); wpt->shortname = xstrdup(tmpnam); wpt->wpt_flags.shortname_is_synthetic = 1; } } void -route_del_wpt( route_head *rte, waypoint *wpt) +route_add_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_add_wpt( rte, wpt, &rte_waypts, 1 ); +} + +void +track_add_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_add_wpt( rte, wpt, &trk_waypts, 0 ); +} + +waypoint * +route_find_waypt_by_name( route_head *rh, const char *name ) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + waypoint *waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + return NULL; +} + +static void +any_route_del_wpt( route_head *rte, waypoint *wpt, int *ct) { dequeue( &wpt->Q ); waypt_free( wpt ); rte->rte_waypt_ct--; - rte_waypts--; + if ( ct ) (*ct)--; } -void -route_free(route_head *rte) +void +route_del_wpt( route_head *rte, waypoint *wpt ) { - if ( rte->rte_name ) { - xfree(rte->rte_name); - } - if ( rte->rte_desc ) { - xfree(rte->rte_desc); - } - rte_waypts -= rte->rte_waypt_ct; - waypt_flush(&rte->waypoint_list); - if ( rte->fs ) { - fs_chain_destroy( rte->fs ); - } - xfree(rte); + any_route_del_wpt( rte, wpt, &rte_waypts ); +} + +void +track_del_wpt( route_head *rte, waypoint *wpt ) +{ + any_route_del_wpt( rte, wpt, &trk_waypts ); } void @@ -160,7 +248,7 @@ route_reverse(const route_head *rte_hd) } } -void +static void common_disp_all(queue *qh, route_hdr rh, route_trl rt, waypt_cb wc) { queue *elem, *tmp; @@ -185,22 +273,336 @@ track_disp_all(route_hdr rh, route_trl rt, waypt_cb wc) common_disp_all(&my_track_head, rh, rt, wc); } -void -route_flush(queue *head) +static void +route_flush_q(queue *head) { queue *elem, *tmp; queue *q; QUEUE_FOR_EACH(head, elem, tmp) { q = dequeue(elem); - route_free((route_head *) q); + any_route_free((route_head *) q); } } +void +route_flush_all_routes(void) +{ + route_flush_q(&my_route_head); + rte_head_ct = 0; + rte_waypts = 0; +} + +void +route_flush_all_tracks(void) +{ + route_flush_q(&my_track_head); + trk_head_ct = 0; + trk_waypts = 0; +} + void route_flush_all() { - route_flush(&my_route_head); - route_flush(&my_track_head); + route_flush_all_tracks(); + route_flush_all_routes(); } +void +route_flush( queue *head ) +{ + queue *elem, *tmp; + queue *q; + QUEUE_FOR_EACH(head, elem, tmp ) { + q = dequeue(elem); + any_route_free((route_head *)q); + } +} + +void +route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ) { + queue *elem, *tmp, *elem2, *tmp2; + route_head *rte_new; + int junk; + if ( !dst_wpt_count ) { + dst_wpt_count = &junk; + } + + if ( !*dst ) { + *dst = xcalloc( 1, sizeof( queue )); + QUEUE_INIT( *dst ); + *dst_count = 0; + *dst_wpt_count = 0; + } + QUEUE_FOR_EACH(src, elem, tmp ) + { + route_head *rte_old = (route_head *)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup( rte_old->rte_name ); + rte_new->rte_desc = xstrdup( rte_old->rte_desc ); + rte_new->rte_url = xstrdup( rte_old->rte_url ); + rte_new->fs = fs_chain_copy( rte_old->fs ); + rte_new->rte_num = rte_old->rte_num; + any_route_add_head( rte_new, *dst ); + QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) + { + any_route_add_wpt( rte_new, waypt_dupe((waypoint *)elem2), dst_wpt_count, 0); + } + (*dst_count)++; + } +} + +void +route_append( queue *src ) +{ + queue *dst = &my_route_head; + route_copy( &rte_head_ct, &rte_waypts, &dst, src ); +} + +void +track_append( queue *src ) +{ + queue *dst = &my_track_head; + route_copy( &trk_head_ct, &trk_waypts, &dst, src ); +} + +void +route_backup(signed int *count, queue **head_bak) +{ + route_copy( count, NULL, head_bak, &my_route_head ); +} + +static void +route_restore_hdr(const route_head *rte) +{ + rte_head_ct++; +} + +static void +track_restore_hdr(const route_head *trk) +{ + trk_head_ct++; +} + +static void +route_restore_tlr(const route_head *rte) +{ +} + +static void +route_restore_wpt(const waypoint *wpt) +{ + rte_waypts++; +} + +static void +track_restore_wpt(const waypoint *wpt) +{ + trk_waypts++; +} + +static void +common_restore_finish(void) +{ + rte_head_ct = 0; + trk_head_ct = 0; + rte_waypts = 0; + trk_waypts = 0; + route_disp_all(route_restore_hdr, route_restore_tlr, route_restore_wpt); + track_disp_all(track_restore_hdr, route_restore_tlr, track_restore_wpt); +} + +void +route_restore( queue *head_bak) +{ + if (head_bak == NULL) return; + + route_flush_q(&my_route_head); + QUEUE_INIT(&my_route_head); + QUEUE_MOVE(&my_route_head, head_bak); + + common_restore_finish(); +} + +void +track_backup(signed int *count, queue **head_bak) +{ + route_copy( count, NULL, head_bak, &my_track_head ); +} + +void +track_restore( queue *head_bak) +{ + if (head_bak == NULL) return; + + route_flush_q(&my_track_head); + QUEUE_INIT(&my_track_head); + QUEUE_MOVE(&my_track_head, head_bak); + + common_restore_finish(); +} + +/* + * Move the entire track queue onto the route queue making no attempt + * at all to "fix" anything in the process. + */ +void +routes_to_tracks(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&my_route_head, elem, tmp) { + route_head *trk = (route_head *) elem; + dequeue(&trk->Q); + ENQUEUE_TAIL(&my_track_head, &trk->Q); + } +} + +/* + * Same, but in opposite direction. + */ +void +tracks_to_routes(void) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(&my_track_head, elem, tmp) { + route_head *trk = (route_head *) elem; + dequeue(&trk->Q); + ENQUEUE_TAIL(&my_route_head, &trk->Q); + } +} + + +/* + * This really makes more sense for tracks than routes. + * Run over all the trackpoints, computing heading (course), speed, and + * and so on. + * + * If trkdatap is non-null upon entry, a pointer to an allocated collection + * (hopefully interesting) statistics about the track will be placed there. + */ +void track_recompute(const route_head *trk, computed_trkdata **trkdatap) +{ + waypoint first; + waypoint *this; + waypoint *prev = &first; + queue *elem, *tmp; + int tkpt = 0; + int pts_hrt = 0; + double tot_hrt = 0.0; + int pts_cad = 0; + double tot_cad = 0.0; + char tkptname[100]; + computed_trkdata *tdata = xcalloc(1, sizeof (computed_trkdata)); + + if (trkdatap) { + *trkdatap = tdata; + } + + first.latitude = 0; + first.longitude = 0; + first.creation_time = 0; + tdata->min_hrt = 9999; + tdata->min_alt = 999999999; + tdata->max_alt = -999999999; + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + time_t timed; + double tlat, tlon, plat, plon, dist; + + this = (waypoint *)elem; + timed = this->creation_time - prev->creation_time; + + /* + * gcdist and heading want radians, not degrees. + */ + tlat = RAD(this->latitude); + tlon = RAD(this->longitude); + plat = RAD(prev->latitude); + plon = RAD(prev->longitude); + this->course = heading_true_degrees(plat, plon, + tlat, tlon); + dist = radtometers(gcdist(plat, plon, tlat, tlon)); + + /* + * Avoid that 6300 mile jump as we move from 0,0. + */ + if (plat && plon) { + tdata->distance_meters += dist; + } + + /* + * If we've moved as much as a meter, recompute speed. + */ + if (timed && (dist > 1)) { + this->speed = dist / labs(timed); + if (this->speed > tdata->max_spd) { + tdata->max_spd = this->speed; + } + if (this->speed < tdata->min_spd) { + tdata->min_spd = this->speed; + } + } + + if ((this->altitude > 0) && (this->altitude < tdata->min_alt)) { + tdata->min_alt = this->altitude; + } + if (this->altitude > tdata->max_alt) { + tdata->max_alt = this->altitude; + } + + if (this->heartrate > 0) { + pts_hrt++; + tot_hrt += (float) this->heartrate; + } + + if ((this->heartrate > 0) && (this->heartrate < tdata->min_hrt)) { + tdata->min_hrt = (int) this->heartrate; + } + + if ((this->heartrate > 0) && (this->heartrate > tdata->max_hrt)) { + tdata->max_hrt = (int) this->heartrate; + } + + if (this->cadence > 0) { + pts_cad++; + tot_cad += (float) this->cadence; + } + + if ((this->cadence > 0) && (this->cadence > tdata->max_cad)) { + tdata->max_cad = (int) this->cadence; + } + + if (this->creation_time && (this->creation_time < tdata->start)) { + tdata->start = this->creation_time; + } + + if (this->creation_time > tdata->end) { + tdata->end = this->creation_time; + if (tdata->start == 0) { + tdata->start = tdata->end; + } + } + prev = this; + if (!this->shortname || !this->shortname[0] ) { + snprintf(tkptname, sizeof(tkptname), "%s-%d", + trk->rte_name ? trk->rte_name : "" , tkpt); + this->shortname = xstrdup(tkptname); + } + tkpt++; + } + + if (pts_hrt > 0) { + tdata->avg_hrt = tot_hrt / (float) pts_hrt; + } + + if (pts_cad > 0) { + tdata->avg_cad = tot_cad / (float) pts_cad; + } + + if (!trkdatap) { + xfree(tdata); + } +} diff --git a/saroute.c b/saroute.c index 11dc7f29a..cd9648cf6 100644 --- a/saroute.c +++ b/saroute.c @@ -25,20 +25,32 @@ #define MYNAME "saroute" #include "defs.h" +#include "grtcirc.h" FILE *infile; char *turns_important = NULL; char *turns_only = NULL; +char *controls = NULL; +char *split = NULL; +char *timesynth = NULL; + +int control = 0; static arglist_t saroute_args[] = { {"turns_important", &turns_important, "Keep turns if simplify filter is used", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"turns_only", &turns_only, "Only read turns; skip all other points", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0 } + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"split", &split, "Split into multiple routes at turns", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"controls", &controls, "Read control points as waypoint/route/none", + "none", ARGTYPE_STRING, ARG_NOMINMAX }, + {"times", ×ynth, "Synthesize track times", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; unsigned short @@ -46,7 +58,9 @@ ReadShort(FILE * f) { gbuint16 result = 0; - fread(&result, sizeof (result), 1, f); + if (!fread(&result, sizeof (result), 1, f)) { + fatal(MYNAME ": Attempt to read past EOF"); + } return le_read16(&result); } @@ -55,7 +69,8 @@ ReadLong(FILE * f) { gbuint32 result = 0; - fread(&result, sizeof (result), 1, f); + if (!fread(&result, sizeof (result), 1, f)) + fatal(MYNAME ": Attempt to read past EOF"); return le_read32(&result); } @@ -65,7 +80,8 @@ ReadRecord(FILE * f, { unsigned char *result = (unsigned char *) xmalloc(size); - fread(result, size, 1, f); + if (!fread(result, size, 1, f)) + fatal(MYNAME ": Attempt to read past EOF"); return result; } @@ -80,6 +96,21 @@ static void rd_init(const char *fname) { infile = xfopen(fname, "rb", MYNAME); + if ( split && (turns_important || turns_only )) { + fatal( MYNAME + ": turns options are not compatible with split\n" ); + } + if ( controls ) { + switch( controls[0] ) { + case 'n': control = 0; break; + case 'r': control = 1; break; + case 'w': control = 2; break; + default: + fatal( MYNAME + ": unrecognized value for 'controls'\n" ); + break; + } + } } static void @@ -104,8 +135,17 @@ my_read(void) gbint32 lon; } *latlon; unsigned short coordcount; - route_head *track_head; + route_head *track_head = NULL; + route_head *old_track_head = NULL; waypoint *wpt_tmp; + char *routename = NULL; + double seglen = 0.0; + long starttime = 0; + long transittime = 0; + double totaldist = 0.0; + double oldlat = 0; + double oldlon = 0; + int first = 0; ReadShort(infile); /* magic */ version = ReadShort(infile); @@ -129,6 +169,11 @@ my_read(void) record = ReadRecord(infile, recsize); stringlen = le_read16((unsigned short *)(record + 0x1a)); + if ( stringlen ) { + routename = (char *)xmalloc( stringlen + 1 ); + routename[stringlen] = '\0'; + memcpy( routename, record+0x1c, stringlen ); + } Skip(infile, stringlen - 4); xfree(record); @@ -139,33 +184,70 @@ my_read(void) /* * here lie the route description records */ - if ( version < 6 ) { + if ( version < 6 || (control == 1)) { track_head = route_head_alloc(); route_add_head(track_head); + if ( control ) { + track_head->rte_name = xstrdup("control points"); + } + else { + track_head->rte_name = xstrdup( routename ); + } } count = ReadLong(infile); while (count) { ReadShort(infile); recsize = ReadLong(infile); - if (version < 6) { + if (version < 6 || control) { double lat; double lon; - + record = ReadRecord(infile, recsize); latlon = (struct ll *)(record); + /* These records are backwards for some reason */ lat = (0x80000000UL - - le_read32(&latlon->lat)) / (double)(0x800000); - lon = (0x80000000UL - le_read32(&latlon->lon)) / (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lat)) / (double)(0x800000); wpt_tmp = waypt_new(); wpt_tmp->latitude = lat; wpt_tmp->longitude = -lon; - wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); - route_add_wpt(track_head, wpt_tmp); + if ( control ) { + int addrlen = le_read16((short *) + (((char *)record)+18)); + int cmtlen = le_read16((short *) + (((char *)record)+20+addrlen)); + wpt_tmp->notes = (char *)xmalloc(cmtlen+1); + wpt_tmp->shortname = (char *)xmalloc(addrlen+1); + wpt_tmp->notes[cmtlen] = '\0'; + wpt_tmp->shortname[addrlen]='\0'; + memcpy(wpt_tmp->notes, + ((char *)record)+22+addrlen, + cmtlen ); + memcpy(wpt_tmp->shortname, + ((char *)record)+20, + addrlen ); + } + else { + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); + } + if ( control == 2 ) { + waypt_add( wpt_tmp ); + } + else { + route_add_wpt(track_head, wpt_tmp); + } xfree(record); + if (version >= 6 ) { + /* + * two longs of scrap after each record, don't know why + */ + ReadLong(infile); + ReadLong(infile); + } } else { Skip(infile, recsize); /* @@ -204,13 +286,52 @@ my_read(void) count = ReadLong(infile); if ( count ) { track_head = route_head_alloc(); - route_add_head(track_head); + if ( timesynth ) { + track_add_head(track_head); + } + else { + route_add_head(track_head); + } + if ( routename && !split ) { + track_head->rte_name = xstrdup( routename ); + } } while (count) { + old_track_head = NULL; ReadShort(infile); recsize = ReadLong(infile); record = ReadRecord(infile, recsize); stringlen = le_read16((unsigned short *)record); + if ( split && stringlen ) { + if ( track_head->rte_waypt_ct ) { + old_track_head = track_head; + track_head = route_head_alloc(); + if ( timesynth ) { + track_add_head( track_head ); + } + else { + route_add_head( track_head ); + } + } // end if + if ( !track_head->rte_name ) { + track_head->rte_name = + (char *)xmalloc(stringlen+1); + strncpy( track_head->rte_name, + (const char *) record+2, stringlen ); + track_head->rte_name[stringlen] = '\0'; + } + } + + if ( timesynth ) { + seglen = le_read_double( + record + 2 + stringlen + 0x08 ); + starttime = le_read32((unsigned long *) + (record + 2 + stringlen + 0x30 )); + transittime = le_read32((unsigned long *) + (record + 2 + stringlen + 0x10 )); + seglen /= 5280*12*2.54/100000; /* to miles */ + } + coordcount = le_read16((unsigned short *) (record + 2 + stringlen + 0x3c)); latlon = (struct ll *)(record + 2 + stringlen + 0x3c + 2); @@ -218,6 +339,9 @@ my_read(void) if (count) { coordcount--; } + + first = 1; + while (coordcount) { double lat; double lon; @@ -233,13 +357,61 @@ my_read(void) wpt_tmp->latitude = lat; wpt_tmp->longitude = -lon; - wpt_tmp->shortname = (char *) xmalloc(7); + if ( stringlen && ((coordcount>1) || count)) { + wpt_tmp->shortname = xmalloc(stringlen+1); + wpt_tmp->shortname[stringlen] = '\0'; + memcpy( wpt_tmp->shortname, + ((char *)record)+2, + stringlen ); + } + else { + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf( wpt_tmp->shortname, "\\%5.5x", + serial++ ); + } + if ( timesynth ) { + if ( !first ) { + double dist = radtomiles(gcdist( + RAD(lat), RAD(-lon), + RAD(oldlat), + RAD(-oldlon) )); + totaldist += dist; + if ( totaldist > seglen ) { + totaldist = seglen; + } + wpt_tmp->creation_time = + gpsbabel_time+starttime+ + transittime * totaldist/seglen; + } + else { + wpt_tmp->creation_time = + gpsbabel_time+starttime; + totaldist = 0; + } + oldlat = lat; + oldlon = lon; + } if ( turns_important && stringlen ) wpt_tmp->route_priority=1; - sprintf( wpt_tmp->shortname, "\\%5.5x", - serial++ ); - if ( !turns_only || stringlen ) - route_add_wpt(track_head, wpt_tmp); + if ( !turns_only || stringlen ) { + if ( timesynth ) { + track_add_wpt(track_head,wpt_tmp); + } + else { + route_add_wpt(track_head, wpt_tmp); + } + if ( old_track_head ) { + if ( timesynth ) { + track_add_wpt(old_track_head, + waypt_dupe(wpt_tmp)); + } + else { + route_add_wpt(old_track_head, + waypt_dupe(wpt_tmp)); + } + old_track_head = NULL; + } + } latlon++; coordcount--; @@ -248,6 +420,7 @@ my_read(void) if ( coordcount == 1 && count == 0 ) { stringlen = 1; } + first = 0; } if ( version > 10 ) { Skip(infile,2*sizeof(gbuint32)); @@ -259,6 +432,9 @@ my_read(void) */ outercount--; } + if ( routename ) { + xfree( routename ); + } } @@ -278,5 +454,6 @@ ff_vecs_t saroute_vecs = { my_read, NULL, NULL, - saroute_args + saroute_args, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/shape.c b/shape.c index cd51d232e..109541238 100644 --- a/shape.c +++ b/shape.c @@ -22,6 +22,7 @@ #include "defs.h" #include "shapelib/shapefil.h" +#if SHAPELIB_ENABLED static SHPHandle ihandle; static DBFHandle ihandledb; static SHPHandle ohandle; @@ -33,6 +34,19 @@ static double *polybufy; static double *polybufz; static const char *ofname; static int nameidx; +static int urlidx; + +static char *opt_name = NULL; +static char *opt_url = NULL; + +static +arglist_t shp_args[] = { + {"name", &opt_name, "Index of name field in .dbf", + NULL, ARGTYPE_STRING, "0", NULL }, + {"url", &opt_url, "Index of URL field in .dbf", + NULL, ARGTYPE_INT, "0", NULL }, + ARG_TERMINATOR +}; static void my_rd_init(const char *fname) @@ -47,9 +61,51 @@ my_rd_init(const char *fname) fatal(MYNAME ":Cannot open dbf file %s for reading\n", fname); } - nameidx = DBFGetFieldIndex( ihandledb, "NAME" ); - if (nameidx == -1) { -// fatal(MYNAME ":dbf file for %s doesn't have 'NAME'\n", fname); + if ( opt_name ) { + if ( opt_name[0] == '?' ) { + int nFields = 0; + int i = 0; + char name[12]; + char *txt = xstrdup(" Database fields\n"); + nFields = DBFGetFieldCount( ihandledb ); + for ( i = 0; i < nFields; i++ ) { + char txtName[50]; + DBFGetFieldInfo( ihandledb, i, name, NULL, NULL); + sprintf( txtName,"%2d %s\n", i, name ); + txt = xstrappend( txt, txtName ); + } + txt = xstrappend( txt, "\n" ); + fatal( txt ); + } + if ( strchr(opt_name, '+')) { + nameidx = -2; + } + else if ( opt_name[0] >= '0' && opt_name[0] <= '9' ) { + nameidx = atoi( opt_name ); + } + else { + nameidx = DBFGetFieldIndex( ihandledb, opt_name ); + if (nameidx == -1) { + fatal(MYNAME ":dbf file for %s doesn't have '%s' field.\n", fname, opt_name); + } + } + } + else { + nameidx = DBFGetFieldIndex( ihandledb, "NAME" ); + if (nameidx == -1) { +// fatal(MYNAME ":dbf file for %s doesn't have 'NAME' field.\n Please specify the name index with the 'name' option.\n", fname); + } + } + if ( opt_url ) { + if ( opt_url[0] >= '0' && opt_url[0] <= '9' ) { + urlidx = atoi( opt_url ); + } + else { + urlidx = DBFGetFieldIndex( ihandledb, opt_url ); + } + } + else { + urlidx = DBFGetFieldIndex( ihandledb, "URL" ); } } @@ -63,20 +119,68 @@ my_read(void) while (npts) { SHPObject *shp; waypoint *wpt; - const char *name; + const char *name = ""; + const char *url; + char *tmpName = NULL; + char *tmpIndex = opt_name; shp = SHPReadObject(ihandle, npts-1); - name = DBFReadStringAttribute(ihandledb, npts-1, nameidx); + if ( nameidx >0 ) { + name = DBFReadStringAttribute(ihandledb, npts-1, nameidx); + } + else { + if ( nameidx == -1 ) { + name = ""; + } + else if (nameidx == -2 ) { + tmpName = xstrdup( "" ); + tmpIndex = opt_name; + while ( tmpIndex ) { + char *tmp2 = tmpIndex; + tmpIndex = strchr(tmpIndex,'+'); + if ( tmpIndex ) { + *tmpIndex = '\0'; + tmpIndex++; + } + if( tmp2[0]>='0' && tmp2[0]<='9' ) { + name = DBFReadStringAttribute( + ihandledb, npts-1, atoi(tmp2)); + } + else { + int idx = 0; + idx = DBFGetFieldIndex( ihandledb, tmp2); + if ( idx >= 0 ) { + name = DBFReadStringAttribute( + ihandledb, npts-1, idx); + } + } + + tmpName = xstrappend(tmpName, name ); + if ( tmpIndex ) { + tmpName = xstrappend( tmpName, " / " ); + } + } + name = tmpName; + } + } + if ( urlidx > 0 ) { + url = DBFReadStringAttribute( ihandledb, npts-1, urlidx); + } + else { + url = NULL; + } + if (shp->nSHPType == SHPT_ARC) { int j; - route_head *track_head = route_head_alloc(); - route_add_head(track_head); + route_head *routehead = route_head_alloc(); + routehead->rte_name = xstrdup(name); + route_add_head(routehead); for (j = 0; j < shp->nVertices; j++) { wpt = waypt_new(); wpt->latitude = shp->padfY[j]; wpt->longitude = shp->padfX[j]; wpt->altitude = shp->padfZ[j]; - route_add_wpt(track_head, wpt); + route_add_wpt(routehead, wpt); } } @@ -84,13 +188,20 @@ my_read(void) wpt = waypt_new(); wpt->latitude = shp->dfYMin; wpt->longitude = shp->dfXMin; - wpt->shortname = strdup(name); + wpt->shortname = xstrdup(name); + if ( url ) { + wpt->url = xstrdup(url); + } waypt_add(wpt); } SHPDestroyObject(shp); npts--; + if ( tmpName ) { + xfree( tmpName ); + tmpName = NULL; + } } } @@ -129,7 +240,7 @@ my_write_wpt(const waypoint *wpt) void poly_init(const route_head *h) { - int ct = route_waypt_count(); + int ct = track_waypt_count(); polybufx = xcalloc(ct, sizeof(double)); polybufy = xcalloc(ct, sizeof(double)); polybufz = xcalloc(ct, sizeof(double)); @@ -149,7 +260,7 @@ void poly_deinit(const route_head *h) { SHPObject *shpobject; - shpobject = SHPCreateSimpleObject(SHPT_ARC, route_waypt_count(), + shpobject = SHPCreateSimpleObject(SHPT_ARC, track_waypt_count(), polybufx, polybufy, polybufz); SHPWriteObject(ohandle, -1, shpobject); SHPDestroyObject(shpobject); @@ -184,7 +295,10 @@ my_write(void) route_disp_all(poly_init, poly_deinit, poly_point); break; case rtedata: - fatal(MYNAME ":Routes are not supported\n"); + fatal(MYNAME ": Routes are not supported\n"); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported\n"); break; } } @@ -199,5 +313,7 @@ ff_vecs_t shape_vecs = { my_read, my_write, NULL, - NULL + shp_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; +#endif /* SHAPELIB_ENABLED */ diff --git a/shapelib/Makefile.in b/shapelib/Makefile.in new file mode 100644 index 000000000..e69de29bb diff --git a/shapelib/dbfopen.c b/shapelib/dbfopen.c index a6a0be543..600271092 100644 --- a/shapelib/dbfopen.c +++ b/shapelib/dbfopen.c @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: dbfopen.c,v 1.1 2004/09/20 17:21:22 robertl Exp $ + * $Id: dbfopen.c,v 1.3 2006/07/13 03:27:54 robertl Exp $ * * Project: Shapelib * Purpose: Implementation of .dbf access API documented in dbf_api.html. @@ -34,6 +34,13 @@ ****************************************************************************** * * $Log: dbfopen.c,v $ + * Revision 1.3 2006/07/13 03:27:54 robertl + * Andy Armstrong turns on -Wall for GCC builds and kills about a sequillion warnings. Most of them aren't "real", but it's still a good thing to clean up. + * (I hope I don't regret this before 1.3.1...) + * + * Revision 1.2 2006/05/07 02:14:35 robertl + * Make shapefile and all palm pdb formats deselectable at build time. + * * Revision 1.1 2004/09/20 17:21:22 robertl * Check in shapelib and experimental prototype of crude shapefile support. * @@ -185,10 +192,13 @@ * Added header. */ -static char rcsid[] = - "$Id: dbfopen.c,v 1.1 2004/09/20 17:21:22 robertl Exp $"; +/*static char rcsid[] = + "$Id: dbfopen.c,v 1.3 2006/07/13 03:27:54 robertl Exp $";*/ #include "shapefil.h" +#include "config.h" + +#if SHAPELIB_ENABLED #include #include @@ -1496,3 +1506,4 @@ DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName) } return(-1); } +#endif diff --git a/shapelib/shpopen.c b/shapelib/shpopen.c index 54d04a5dc..9e75ec7d1 100644 --- a/shapelib/shpopen.c +++ b/shapelib/shpopen.c @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: shpopen.c,v 1.2 2004/09/27 01:13:58 robertl Exp $ + * $Id: shpopen.c,v 1.4 2006/07/13 03:27:54 robertl Exp $ * * Project: Shapelib * Purpose: Implementation of core Shapefile read/write functions. @@ -34,6 +34,13 @@ ****************************************************************************** * * $Log: shpopen.c,v $ + * Revision 1.4 2006/07/13 03:27:54 robertl + * Andy Armstrong turns on -Wall for GCC builds and kills about a sequillion warnings. Most of them aren't "real", but it's still a good thing to clean up. + * (I hope I don't regret this before 1.3.1...) + * + * Revision 1.3 2006/05/07 02:14:35 robertl + * Make shapefile and all palm pdb formats deselectable at build time. + * * Revision 1.2 2004/09/27 01:13:58 robertl * warning fixes in shapelib. From Alexander Stohr. * @@ -164,10 +171,12 @@ * */ -static char rcsid[] = - "$Id: shpopen.c,v 1.2 2004/09/27 01:13:58 robertl Exp $"; +/*static char rcsid[] = + "$Id: shpopen.c,v 1.4 2006/07/13 03:27:54 robertl Exp $";*/ #include "shapefil.h" +#include "config.h" +#if SHAPELIB_ENABLED #include #include @@ -1870,3 +1879,4 @@ SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ) return bAltered; } +#endif diff --git a/smplrout.c b/smplrout.c index bd9fb8dcd..e82452199 100644 --- a/smplrout.c +++ b/smplrout.c @@ -18,20 +18,65 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -#include + +/* The following comments are from an email I wrote to Paul Fox in November + * 2005 in an attempt to explain how the cross track error minimization method + * works (RLP 2005): + * + * It's pretty simple, really: for each triplet of vertices A-B-C, we compute + * how much cross-track error we'd introduce by going straight from A to C + * (the maximum cross-track error for that segment is the height of the + * triangle ABC, measured between vertex B and edge AC.) If we need to remove + * 40 points, we just sort the points by that metric and remove the 40 + * smallest ones. + * + * It's actually a little more complicated than that, because removing a + * point changes the result for its two nearest neighbors. When we remove + * one, we recompute the neighbors and then sort them back into the list + * at their new locations. + * + * As you can see, this hasn't been shown to be an optimal algorithm. After + * all, removing one high-xte point might create two very low-xte neighbors + * that more than make up for the high xte of the original point. I believe + * the optimal algorithm would be NP-complete, but I haven't proven it. This + * is really more of a heuristic than anything, but it seems to work well for + * the routes I've fed it. + * + * Not in that email was an explanation of how the pathlength-based calculation + * works: instead of computing the height of the triangle, we just compute + * the difference in pathlength from taking the direct route. This case, + * too, is only a heuristic, as it's possible that a different combination or + * order of point removals could lead to a smaller number of points with less + * reduction in path length. In the case of pathlength, error is cumulative. + */ + + #include "defs.h" +#include "filterdefs.h" #include "grtcirc.h" #define MYNAME "Route simplification filter" static int count = 0; +static double totalerror = 0; +static double error = 0; + static char *countopt = NULL; +static char *erroropt = NULL; +static char *xteopt = NULL; +static char *lenopt = NULL; static arglist_t routesimple_args[] = { {"count", &countopt, "Maximum number of points in route", - NULL, ARGTYPE_INT | ARGTYPE_REQUIRED}, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_INT | ARGTYPE_BEGIN_REQ | ARGTYPE_BEGIN_EXCL, "1", NULL}, + {"error", &erroropt, "Maximum error", NULL, + ARGTYPE_STRING | ARGTYPE_END_REQ | ARGTYPE_END_EXCL, "0", NULL}, + {"crosstrack", &xteopt, "Use cross-track error (default)", NULL, + ARGTYPE_BOOL | ARGTYPE_BEGIN_EXCL, ARG_NOMINMAX }, + {"length", &lenopt, "Use arclength error", NULL, + ARGTYPE_BOOL | ARGTYPE_END_EXCL, ARG_NOMINMAX }, + ARG_TERMINATOR }; struct xte_intermed; @@ -98,10 +143,21 @@ compute_xte( struct xte *xte_rec ) { } wpt2 = xte_rec->intermed->next->wpt; - xte_rec->distance = linedist( + if ( xteopt || !lenopt ) { + xte_rec->distance = radtomiles(linedist( wpt1->latitude, wpt1->longitude, wpt2->latitude, wpt2->longitude, - wpt3->latitude, wpt3->longitude ); + wpt3->latitude, wpt3->longitude )); + } + else { + xte_rec->distance = radtomiles( + gcdist( wpt1->latitude, wpt1->longitude, + wpt3->latitude, wpt3->longitude ) + + gcdist( wpt3->latitude, wpt3->longitude, + wpt2->latitude, wpt2->longitude ) - + gcdist( wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude )); + } } @@ -133,9 +189,10 @@ routesimple_head( const route_head *rte ) /* build array of XTE/wpt xref records */ xte_count = 0; tmpprev = NULL; + totalerror = 0; /* short-circuit if we already have fewer than the max points */ - if ( count >= rte->rte_waypt_ct) return; + if ( countopt && count >= rte->rte_waypt_ct) return; xte_recs = (struct xte *) xcalloc( rte->rte_waypt_ct, sizeof (struct xte)); cur_rte = rte; @@ -196,9 +253,22 @@ routesimple_tail( const route_head *rte ) xte_recs[i].intermed->xte_rec = xte_recs+i; } /* while we still have too many records... */ - while ( count < xte_count ) { + while ( (countopt && count < xte_count) || (erroropt && totalerror < error) ) { i = xte_count - 1; /* remove the record with the lowest XTE */ + if ( erroropt ) { + if ( xteopt ) { + if ( i > 1 ) { + totalerror = xte_recs[i-1].distance; + } + else { + totalerror = xte_recs[i].distance; + } + } + if ( lenopt ) { + totalerror += xte_recs[i].distance; + } + } route_del_wpt( (route_head *)(void *)rte, (waypoint *)(void *)(xte_recs[i].intermed->wpt)); @@ -234,13 +304,29 @@ routesimple_process( void ) void routesimple_init(const char *args) { + char *fm = NULL; count = 0; + if ( !!countopt == !!erroropt ) { + fatal( MYNAME ": You must specify either count or error, but not both.\n"); + } + if ( xteopt && lenopt ) { + fatal( MYNAME ": crosstrack and length may not be used together.\n"); + } + if ( !xteopt && !lenopt ) { + xteopt = (char *)xmalloc( 1 ); + } + if (countopt) { count = atol(countopt); } - else { - fatal( MYNAME ": You must specify a maximum size for the new route with 'count' option.\n"); + if (erroropt) { + error = strtod(erroropt, &fm); + + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to miles */ + error *= .6214; + } } } diff --git a/sort.c b/sort.c index e91af8317..52c9bd810 100644 --- a/sort.c +++ b/sort.c @@ -19,73 +19,54 @@ */ #include "defs.h" +#include "filterdefs.h" -extern queue waypt_head; +#if FILTERS_ENABLED typedef enum { sm_unknown = 0, sm_gcid, sm_shortname, - sm_description + sm_description, + sm_time } sort_mode_; sort_mode_ sort_mode = sm_shortname; /* How are we sorting these? */ -static char *opt_sm_gcid, *opt_sm_shortname, *opt_sm_description; +static char *opt_sm_gcid, *opt_sm_shortname, *opt_sm_description, *opt_sm_time; static arglist_t sort_args[] = { {"gcid", &opt_sm_gcid, "Sort by numeric geocache ID", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"shortname", &opt_sm_shortname, "Sort by waypoint short name", - NULL, ARGTYPE_BOOL }, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, {"description", &opt_sm_description, "Sort by waypoint description", - NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"time", &opt_sm_time, "Sort by time", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static int -sort_comp(const void * a, const void * b) +sort_comp(const queue * a, const queue * b) { - const waypoint *x1 = *(waypoint **)a; - const waypoint *x2 = *(waypoint **)b; + const waypoint *x1 = (waypoint *)a; + const waypoint *x2 = (waypoint *)b; switch (sort_mode) { - case sm_gcid: return x1->gc_data.id > x2->gc_data.id; + case sm_gcid: return x1->gc_data.id - x2->gc_data.id; case sm_shortname: return strcmp (x1->shortname, x2->shortname); case sm_description: return strcmp (x1->description, x2->description); - default: abort(); /* Internal caller error. */ + case sm_time: return x1->creation_time - x2->creation_time; + default: abort(); return 0; /* Internal caller error. */ } } void sort_process(void) { - queue * elem, * tmp; - waypoint ** comp; - int i = 0, wc; - - wc = waypt_count(); - - comp = (waypoint **) xcalloc(wc, sizeof(*comp)); - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - comp[i] = (waypoint *)elem; - waypt_del(comp[i]); /* Pop this waypoint off the master Q */ - i++; - } - - qsort(comp, wc, sizeof(waypoint *), sort_comp); - - /* - * Now re-add the list back. - */ - for (i = 0; i < wc ; i++) { - waypt_add(comp[i]); - } - - if (comp) - xfree(comp); + sortqueue(&waypt_head, sort_comp); } void @@ -97,6 +78,8 @@ sort_init(const char *args) sort_mode = sm_shortname; if (opt_sm_description) sort_mode = sm_description; + if (opt_sm_time) + sort_mode = sm_time; } filter_vecs_t sort_vecs = { @@ -106,3 +89,4 @@ filter_vecs_t sort_vecs = { NULL, sort_args }; +#endif // FILTERS_ENABLED diff --git a/stackfilter.c b/stackfilter.c index 494947042..e8bbf71e6 100644 --- a/stackfilter.c +++ b/stackfilter.c @@ -18,12 +18,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -#include + #include "defs.h" +#include "filterdefs.h" -#define MYNAME "Stack filter" +#if FILTERS_ENABLED -extern queue waypt_head; +#define MYNAME "Stack filter" static char *opt_push = NULL; static char *opt_copy = NULL; @@ -40,29 +41,33 @@ static int swapdepth = 0; static arglist_t stackfilt_args[] = { {"push", &opt_push, "Push waypoint list onto stack", NULL, - ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL}, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, {"pop", &opt_pop, "Pop waypoint list from stack", NULL, - ARGTYPE_BOOL}, + ARGTYPE_BOOL, ARG_NOMINMAX}, {"swap", &opt_swap, "Swap waypoint list with item on stack", - NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_BOOL}, + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, {"copy", &opt_copy, "(push) Copy waypoint list", NULL, - ARGTYPE_BOOL}, + ARGTYPE_BOOL, ARG_NOMINMAX}, {"append", &opt_append, "(pop) Append list", NULL, - ARGTYPE_BEGIN_EXCL | ARGTYPE_BOOL}, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX}, {"discard", &opt_discard, "(pop) Discard top of stack", - NULL, ARGTYPE_BOOL}, + NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, {"replace", &opt_replace, "(pop) Replace list (default)", - NULL, ARGTYPE_END_EXCL | ARGTYPE_BOOL}, + NULL, ARGTYPE_END_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX}, {"depth", &opt_depth, "(swap) Item to use (default=1)", - NULL, ARGTYPE_INT}, + NULL, ARGTYPE_INT, "0", NULL}, {"nowarn", &nowarn, "Suppress cleanup warning", NULL, - ARGTYPE_BOOL | ARGTYPE_HIDDEN}, - {0, 0, 0, 0, 0} + ARGTYPE_BOOL | ARGTYPE_HIDDEN, ARG_NOMINMAX}, + ARG_TERMINATOR }; struct stack_elt { queue waypts; + queue routes; + queue tracks; unsigned int waypt_ct; + int route_count; + int track_count; struct stack_elt *next; } *stack = NULL; @@ -78,6 +83,7 @@ stackfilt_process(void) if ( opt_push ) { tmp_elt = (struct stack_elt *)xmalloc(sizeof(struct stack_elt)); + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head); tmp_elt->waypt_ct = waypt_count(); set_waypt_count(0); @@ -88,6 +94,23 @@ stackfilt_process(void) waypt_add( waypt_dupe((waypoint *)elem)); } } + + tmp = NULL; + route_backup( &(tmp_elt->route_count), &tmp ); + QUEUE_MOVE( &(tmp_elt->routes), tmp ); + xfree( tmp ); + if ( !opt_copy ) { + route_flush_all_routes(); + } + + tmp = NULL; + track_backup( &(tmp_elt->track_count), &tmp ); + QUEUE_MOVE( &(tmp_elt->tracks), tmp ); + xfree( tmp ); + if ( !opt_copy ) { + route_flush_all_tracks(); + } + } else if ( opt_pop ) { tmp_elt = stack; @@ -98,15 +121,25 @@ stackfilt_process(void) QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { waypt_add( (waypoint *)elem); } + route_append( &(stack->routes)); + route_flush( &(stack->routes)); + track_append( &(stack->tracks)); + route_flush( &(stack->tracks)); } else if ( opt_discard ) { - waypt_flush( &(stack->waypts) ); + waypt_flush( &(stack->waypts)); + route_flush( &(stack->routes)); + route_flush( &(stack->tracks)); } else { waypt_flush( &waypt_head ); QUEUE_MOVE(&(waypt_head), &(stack->waypts) ); set_waypt_count(stack->waypt_ct); - } + + route_restore( &(stack->routes)); + track_restore( &(stack->tracks)); + } + stack = tmp_elt->next; xfree( tmp_elt ); } @@ -123,6 +156,20 @@ stackfilt_process(void) QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head ); QUEUE_MOVE(&waypt_head, &tmp_queue ); + QUEUE_MOVE(&tmp_queue, &(tmp_elt->routes)); + tmp = NULL; + route_backup( &(tmp_elt->route_count), &tmp); + QUEUE_MOVE(&(tmp_elt->routes), tmp ); + xfree( tmp ); + route_restore( &tmp_queue ); + + QUEUE_MOVE(&tmp_queue, &(tmp_elt->tracks)); + tmp = NULL; + track_backup( &(tmp_elt->track_count), &tmp); + QUEUE_MOVE(&(tmp_elt->tracks), tmp ); + xfree( tmp ); + track_restore( &tmp_queue ); + tmp_count = waypt_count(); set_waypt_count( tmp_elt->waypt_ct ); tmp_elt->waypt_ct = tmp_count; @@ -199,3 +246,5 @@ filter_vecs_t stackfilt_vecs = { stackfilt_exit, stackfilt_args }; + +#endif // FILTERS_ENABLED diff --git a/stmsdf.c b/stmsdf.c new file mode 100644 index 000000000..bc2e861e5 --- /dev/null +++ b/stmsdf.c @@ -0,0 +1,724 @@ +/* + + Support for Suunto Trackmanager SDF format. + + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +/* + 2006/04/05: initial release (not published in GPSBbabel) + 2006/07/19: finished reader and writer for type 4,5,28 of ver. 1 + 2006/10/31: remove wptdata from case statement (data_write) + + ToDo: Ascending/Descending +*/ + + +#include +#include +#include +#include + +#include "defs.h" +#include "csv_util.h" +#include "strptime.h" +#include "jeeps/gpsmath.h" +#include "grtcirc.h" + +#include + +#define MYNAME "stmsdf" + +#define ALT(a) (a->altitude != unknown_alt) ? a->altitude : 0 + +typedef enum { + sdf_unknown, + sdf_header, + sdf_points, + sdf_custom +} sdf_section_e; + +static gbfile *fin, *fout; + +// Empty structs aren't C89. But this wasn't being used anyway. +//typedef struct stmsdf_s { +//} stmsdf_t; + +static int lineno; +static int datum; +static int datum86; +static int filetype; +static route_head *route; +static queue trackpts; +static char *rte_name; +static char *rte_desc; + +static waypoint *trkpt_out; +static route_head *trk_out; + +static double trkpt_dist; +static double minalt, maxalt, maxspeed; +static double this_distance, all_dist; +static time_t this_time, all_time; +static double all_asc, all_desc; +static int this_index; /* from 1 to ... */ +static int all_points; +static int this_points; +static int saved_points; +static time_t start_time; +static unsigned char this_valid; + +#define route_index this_index +#define track_index this_index +#define all_route_points all_points +#define all_track_points all_points +#define route_points this_points +#define track_points this_points +#define saved_track_points saved_points +#define this_route_valid this_valid + +/* placeholders for options */ + +static char *opt_route_index; +static int opt_route_index_value; + +static +arglist_t stmsdf_args[] = { + { "index", &opt_route_index, + "Index of route (if more the one in source)", "1", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +/* ----------------------------------------------------------- */ + +static void +parse_header(char *line) +{ + char *str; + char *key = NULL; + char *prod = NULL; + int column = -1; + + while ((str = csv_lineparse(line, "=", "", lineno))) + { + line = NULL; + column++; + + switch(column) { + case 0: + key = xstrdup(str); + break; + case 1: + if (case_ignore_strcmp(key, "DATUM") == 0) datum = GPS_Lookup_Datum_Index(str); + else if (case_ignore_strcmp(key, "FILEVERSION") == 0) { + int ver = atoi(str); + is_fatal( (ver != 1), + MYNAME ": This version '%d' is not yet supported. Please report!", ver); + } + else if (case_ignore_strcmp(key, "NAME") == 0) rte_name = xstrdup(str); + else if (case_ignore_strcmp(key, "NOTES") == 0) /* ToDo */; + else if (case_ignore_strcmp(key, "SOURCE") == 0) rte_desc = xstrdup(str); + else if (case_ignore_strcmp(key, "TYPE") == 0) { + filetype = atoi(str); + switch(filetype) { + case 4: /* M9 TrackLog (Suunto Sail Manager) */ + case 5: /* route */ + case 28: /* X9 TrackLog (Suunto Trek Manager */ + break; + + case 78: prod = "S6 SkiChrono"; + case 79: prod = "S6 Skilog"; + + default: + if (prod == NULL) prod = "unknown"; + fatal(MYNAME ": Unsupported file type (%s, type %d)!\n", prod, filetype); + } + } + break; + } + } + if (key) xfree(key); + +} + +static int +track_qsort_cb(const void *a, const void *b) +{ + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return wa->creation_time - wb->creation_time; +} + +static void +finalize_tracks(void) +{ + waypoint **list; + int count = 0; + queue *elem, *tmp; + int index; + route_head *track = NULL; + int trackno = 0; + + count = 0; + QUEUE_FOR_EACH(&trackpts, elem, tmp) { count++; }; + if (count == 0) return; + + list = (void *)xmalloc(count * sizeof(*list)); + + index = 0; + QUEUE_FOR_EACH(&trackpts, elem, tmp) { + list[index] = (waypoint *)elem; + dequeue(elem); + index++; + } + + qsort(list, count, sizeof(*list), track_qsort_cb); + + for (index = 0; index < count; index++) { + waypoint *wpt = list[index]; + if (wpt->centiseconds == 2) { /* log continued */ + track = NULL; + } + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + trackno++; + if (rte_name != NULL) { + if (trackno > 1) + xasprintf(&track->rte_name, "%s (%d)", rte_name, trackno); + else + track->rte_name = xstrdup(rte_name); + } + if (rte_desc != NULL) + track->rte_desc = xstrdup(rte_desc); + } + track_add_wpt(track, wpt); + if (wpt->centiseconds == 1) { /* log pause */ + track = NULL; + } + wpt->centiseconds = 0; + } + + xfree(list); +} + +static void +parse_point(char *line) +{ + char *str; + int column = -1; + int what = -1; /* -1 = unknown, 0 = tp, 1 = mp, 2 = wp, 3 = ap */ + waypoint *wpt = NULL; + char *cx; + int hour, min, sec, day, month, year; + + year = hour = -1; + + while ((str = csv_lineparse(line, ",", "", lineno))) + { + + line = NULL; + column++; + + switch(column) { + + case 0: + if (strcmp(str, "\"TP\"") == 0) { + what = 0; + column++; /* skip name */ + } + else if (strcmp(str, "\"MP\"") == 0) what = 1; + else if (strcmp(str, "\"WP\"") == 0) what = 2; + else if (strcmp(str, "\"AP\"") == 0) what = 3; + else { + warning(MYNAME ": Unknown point type %s at line %d!\n", str, lineno); + return; + } + wpt = waypt_new(); + break; + + case 1: + wpt->shortname = csv_stringclean(str, "\""); + if ((what == 2) || (what == 3)) column += 2; /* doesn't have date and time */ + break; + case 2: + sscanf(str, "%d.%d.%d", &day, &month, &year); + break; + case 3: + while ((cx = strchr(str, '.'))) *cx = ':'; + sscanf(str, "%d:%d:%d", &hour, &min, &sec); + break; + case 4: + wpt->latitude = atof(str); + break; + case 5: + wpt->longitude = atof(str); + break; + case 6: + wpt->altitude = atof(str); + break; + case 7: + switch(what) { + case 0: + wpt->speed = atof(str) * 3.6; break; + case 3: + wpt->proximity = atof(str); + xasprintf(&wpt->notes, "Alarm point: radius=%s", str); + break; + } + break; + case 8: + if (what == 0) wpt->course = atof(str); + break; + case 9: + case 10: + break; + case 11: + if (what == 1) wpt->centiseconds = atoi(str); /* memory point type */ + break; + } + } + + if ((year > -1) && (hour > -1)) { + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + wpt->creation_time = mklocaltime(&tm); + } + + if (datum != datum86) { + double ht; + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0, + &wpt->latitude, &wpt->longitude, &ht, datum); + } + + switch(what) { + case 0: + case 1: + ENQUEUE_TAIL(&trackpts, &wpt->Q); + break; + case 2: + case 3: + if (route == NULL) { + route = route_head_alloc(); + route_add_head(route); + } + route_add_wpt(route, wpt); + break; + } +} + +/* ----------------------------------------------------------- */ + +static void +rd_init(const char *fname) +{ + fin = gbfopen(fname, "r", MYNAME); + + lineno = 0; + route = NULL; + datum = datum86 = GPS_Lookup_Datum_Index("WGS84"); + filetype = 28; + rte_name = rte_desc = NULL; + + QUEUE_INIT(&trackpts); +} + +static void +rd_deinit(void) +{ + gbfclose(fin); + if (rte_name) xfree(rte_name); + if (rte_desc) xfree(rte_desc); +} + +static void +data_read(void) +{ + char *buf; + sdf_section_e section = sdf_unknown; + + while ((buf = gbfgetstr(fin))) + { + char *cin = lrtrim(buf); + lineno++; + + if (*cin == '\0') continue; + + if (*cin == '[') + { + char *cend = strchr(++cin, ']'); + + if (cend != NULL) + { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) + fatal(MYNAME ": Invalid section header!\n"); + + if (case_ignore_strcmp(cin, "HEADER") == 0) section = sdf_header; + else if (case_ignore_strcmp(cin, "POINTS") == 0) section = sdf_points; + else if (case_ignore_strncmp(cin, "CUSTOM", 6) == 0) section = sdf_custom; + else { + warning(MYNAME ": Unknown section \"%s\". Please report.\n", cin); + section = sdf_unknown; + } + } + else switch(section) + { + case sdf_header: + parse_header(cin); + break; + case sdf_points: + parse_point(cin); + break; + case sdf_custom: + case sdf_unknown: break; + } + } + finalize_tracks(); /* memory points can be at the end of all trackpoints */ +} + + +static void +calculate(const waypoint *wpt, double *dist, double *speed, double *course, + double *asc, double *desc) +{ + if (trkpt_out != NULL) { + + time_t time; + + *course = heading_true_degrees( + RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), + RAD(wpt->latitude), RAD(wpt->longitude)); + + *dist = radtometers(gcdist( + RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), + RAD(wpt->latitude), RAD(wpt->longitude))); + if (*dist < 0.1) *dist = 0; /* calc. diffs on 32- and 64-bit hosts */ + + time = wpt->creation_time - trkpt_out->creation_time; + if (time == 0) + *speed = 0; + else + *speed = *dist / (double)time; + + if (asc && desc && (trkpt_out->altitude != unknown_alt) && (wpt->altitude != unknown_alt)) { + double dh = wpt->altitude - trkpt_out->altitude; + if (dh > 0) + *asc += dh; + else + *desc -= dh; + } + + } + else { + *speed = 0; + *dist = 0; + *course = 0; + if (asc) *asc = 0; + if (desc) *desc = 0; + } + if (wpt->speed != unknown_speed) *speed = wpt->speed / 3.6; /* -> meters per second */ + if (wpt->course != unknown_course) *course = wpt->course; +} + +/* pre-calculation callbacks */ + +static void +any_hdr_calc_cb(const route_head *trk) +{ + + trkpt_out = NULL; + this_distance = 0; + this_time = 0; + this_points = 0; + + this_index++; + this_valid = ((opt_route_index_value < 1) || (opt_route_index_value == this_index)); + if (! this_valid) return; + + if (!rte_name && trk->rte_name) { + rte_name = trk->rte_name; + rte_desc = trk->rte_desc; + } + + trk_out = (route_head *)trk; +} + +static void +any_waypt_calc_cb(const waypoint *wpt) +{ + double speed, course, dist; + + /* we can only write ONE route */ + if (! this_valid) return; + + if ((all_points == 0) && (this_points == 0)) start_time = wpt->creation_time; + + this_points++; + + if ((wpt->altitude != unknown_alt) && (wpt->altitude < minalt)) minalt = wpt->altitude; + if ((wpt->altitude != unknown_alt) && (wpt->altitude > maxalt)) maxalt = wpt->altitude; + calculate(wpt, &dist, &speed, &course, &all_asc, &all_desc); + if (speed > maxspeed) maxspeed = speed; + + this_distance = this_distance + dist; + if (trkpt_out != NULL) + this_time += (wpt->creation_time - trkpt_out->creation_time); + + trkpt_out = (waypoint *)wpt; +} + +static void +any_tlr_calc_cb(const route_head *trk) +{ + if (! this_valid) return; + + all_dist += this_distance; + all_time += this_time; + all_points += this_points; +} + +/* write callbacks */ + +static void +track_disp_hdr_cb(const route_head *trk) +{ + track_index++; + track_points = 0; + trk_out = (route_head *)trk; + trkpt_out = NULL; +} + + +static void +track_disp_wpt_cb(const waypoint *wpt) +{ + struct tm tm; + char tbuf[32]; + double course, speed, dist; + int flag = 0; + + track_points++; + all_track_points++; + + tm = *localtime(&wpt->creation_time); + strftime(tbuf, sizeof(tbuf), "%d.%m.%Y,%H:%M.%S", &tm); + + calculate(wpt, &dist, &speed, &course, NULL, NULL); + trkpt_dist = trkpt_dist + dist; + + if (track_points == trk_out->rte_waypt_ct) { /* I'm the last in that list */ + if (all_track_points != saved_track_points) { /* but not the overall latest */ + flag = 1; + } + } + else if (track_points == 1) { /* I'm the first in that list */ + if (all_track_points > 1) { /* but not the first ever seen */ + flag = 2; + } + } + + if (flag == 1) { + char *name = wpt->shortname; + if (name == NULL) name = "Log paused"; + gbfprintf(fout, "\"MP\",\"%s\"", name); + } + else if (flag == 2) { + char *name = wpt->shortname; + if (name == NULL) name = "Log continued"; + gbfprintf(fout, "\"MP\",\"%s\"", name); + } + else + gbfprintf(fout, "\"TP\""); + + gbfprintf(fout, ",%s,%.6lf,%.6lf,%.f,%.2f", + tbuf, + wpt->latitude, wpt->longitude, ALT(wpt), speed); + if (flag) + gbfprintf(fout, ",0,0,%d", flag); /* press, temperature, memory point type */ + else + gbfprintf(fout, ",%.1f", course); + + if (trkpt_dist != 0) + gbfprintf(fout, ",%.6f\n", trkpt_dist); + else + gbfprintf(fout, ",0\n"); + + trkpt_out = (waypoint *)wpt; +} + +static void +track_disp_tlr_cb(const route_head *rte) +{ + trkpt_out = NULL; +} + +static void +route_disp_hdr_cb(const route_head *rte) +{ + route_index++; + this_route_valid = ((opt_route_index_value < 1) || (opt_route_index_value == track_index)); +} + +static void +route_disp_wpt_cb(const waypoint *wpt) +{ + if (this_route_valid) { + gbfprintf(fout, "\"WP\",\"%s\",%.8lf,%.8lf,%.f\n", + wpt->shortname, wpt->latitude, wpt->longitude, ALT(wpt)); + } +} + +static void +track_disp_custom_cb(const waypoint *wpt) +{ + if (wpt->creation_time && (wpt->altitude != unknown_alt)) { + gbfprintf(fout, "%lu,%.f\n", wpt->creation_time - start_time, wpt->altitude); + } +} + +static void +wr_init(const char *fname) +{ + fout = gbfopen(fname, "w", MYNAME); +} + +static void +wr_deinit(void) +{ + gbfclose(fout); +} + +static void +data_write(void) +{ + gbfprintf(fout, "[HEADER]\n"); + gbfprintf(fout, "FILEVERSION=1\n"); + gbfprintf(fout, "SOURCE=FILE\n"); + gbfprintf(fout, "DATUM=WGS84\n"); + + rte_name = NULL; + rte_desc = NULL; + trkpt_out = NULL; + opt_route_index_value = -1; /* take all tracks from data pool */ + track_index = 0; + minalt = -unknown_alt; + maxalt = unknown_alt; + maxspeed = 0; + all_dist = 0; + all_time = 0; + all_asc = 0; + all_desc = 0; + all_points = 0; + start_time = 0; + + + switch(global_opts.objective) + { + case wptdata: + break; + + case rtedata: + gbfprintf(fout, "TYPE=5\n"); + + opt_route_index_value = atoi(opt_route_index); + route_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); + gbfprintf(fout, "DISTANCE=%.f\n", all_dist); + if (rte_name) gbfprintf(fout, "NAME=%s\n", rte_name); + gbfprintf(fout, "[POINTS]\n"); + if (route_points > 0) { + track_index = 0; + route_disp_all(route_disp_hdr_cb, NULL, route_disp_wpt_cb); + } + break; + + case trkdata: + gbfprintf(fout, "TYPE=28\n"); + + track_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); + if (all_track_points > 0) { + if (rte_name) gbfprintf(fout, "NAME=%s\n", rte_name); + if (minalt != -unknown_alt) gbfprintf(fout, "MINALT=%.f\n", minalt); + if (maxalt != unknown_alt) gbfprintf(fout, "MAXALT=%.f\n", maxalt); + gbfprintf(fout, "MAXSPEED=%.2f\n", maxspeed); + gbfprintf(fout, "DISTANCE=%.f\n", all_dist); + gbfprintf(fout, "DURATION=%lu\n", all_time); +// gbfprintf(fout, "TOTASC=%.f\n", all_asc); +// gbfprintf(fout, "TOTDSC=%.f\n", all_desc); + if (start_time) { + struct tm tm; + char tbuf[32]; + + tm = *localtime(&start_time); + strftime(tbuf, sizeof(tbuf), "%d.%m.%Y %H:%M.%S", &tm); + gbfprintf(fout, "DATE=%s\n", tbuf); + } + if (all_time) gbfprintf(fout, "AVGSPEED=%.2f\n", all_dist / (double)all_time); + } + gbfprintf(fout, "[POINTS]\n"); + if (all_track_points > 0) { + + trkpt_dist = 0; + saved_track_points = all_track_points; + all_track_points = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + + if (start_time) { + gbfprintf(fout, "[CUSTOM1]\n"); + track_index = 0; + track_disp_all(NULL, NULL, track_disp_custom_cb); + } + } + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +/* ------------------------------------------------------------------ */ + +ff_vecs_t stmsdf_vecs = { + ff_type_file, + { ff_cap_none, + ff_cap_read | ff_cap_write, + ff_cap_read | ff_cap_write }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + stmsdf_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +}; + +/* ================================================================== */ diff --git a/stmwpp.c b/stmwpp.c new file mode 100644 index 000000000..288b21117 --- /dev/null +++ b/stmwpp.c @@ -0,0 +1,303 @@ + /* + + Support for "Suunto Trek Manager" (STM) WaypointPlus files, + see homepage "http://www.suunto.fi" for more details, + + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "csv_util.h" +#include +#include +#include + +static gbfile *fin, *fout; +static route_head *track, *route; +static waypoint *wpt; + +#define MYNAME "STMwpp" + +#define STM_NOTHING 0 +#define STM_WAYPT 1 +#define STM_TRKPT 2 +#define STM_RTEPT 3 + +static int track_index; +static int track_num; +static int what; + +static char *index_opt = NULL; + +static +arglist_t stmwpp_args[] = +{ + {"index", &index_opt, "Index of route/track to write (if more the one in source)", + NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR +}; + + +static void +stmwpp_rd_init(const char *fname) +{ + fin = gbfopen(fname, "rb", MYNAME); + track = NULL; + route = NULL; + wpt = NULL; +} + +static void +stmwpp_rd_deinit(void) +{ + gbfclose(fin); +} + +static void +stmwpp_data_read(void) +{ + char *buff; + + what = STM_NOTHING; + buff = gbfgetstr(fin); + buff = (buff == NULL) ? "" : buff; + + if (strncmp(buff, "Datum,WGS 84,WGS 84,", 20) != 0) + fatal(MYNAME ": Invalid GPS datum or not \"WaypointPlus\"\" file!\n"); + + while ((buff = gbfgetstr(fin))) + { + char *c; + int column = -1; + struct tm time; + + wpt = NULL; + memset(&time, 0, sizeof(time)); + + c = csv_lineparse(buff, ",", "", column++); + while (c != NULL) + { + int new_what; + + switch(column) + { + case 0: + if (case_ignore_strcmp(c, "WP") == 0) + { + new_what = STM_WAYPT; + } + else if (case_ignore_strcmp(c, "TP") == 0) + { + new_what = STM_TRKPT; + } + else + fatal(MYNAME ": Unknown feature \"%s\"!\n", c); + + if ((what != STM_NOTHING) && (new_what != what)) + fatal(MYNAME ": Only one feature (route or track) is supported by STM!\n"); + + what = new_what; + wpt = waypt_new(); + break; + + case 1: + if (what == STM_TRKPT) column++; /* no name -> skip column two */ + break; + + case 2: + wpt->shortname = xstrdup(c); + break; + + case 3: + wpt->latitude = atof(c); + break; + + case 4: + wpt->longitude = atof(c); + break; + + case 5: + sscanf(c, "%d/%d/%d", &time.tm_mon, &time.tm_mday, &time.tm_year); + break; + + case 6: + sscanf(c, "%d:%d:%d.%d", &time.tm_hour, &time.tm_min, &time.tm_sec, &wpt->centiseconds); + if (what == STM_TRKPT) + wpt->centiseconds /= 10; + break; + + default: + break; + } + c = csv_lineparse(NULL, ",", "", column++); + } + if (wpt != NULL) + { + time.tm_year -= 1900; + time.tm_mon--; + wpt->creation_time = mkgmtime(&time); + + switch(what) + { + case STM_RTEPT: + if (route == NULL) { + route = route_head_alloc(); + route_add_head(route); + } + route_add_wpt(route, wpt); + break; + + case STM_WAYPT: + waypt_add(wpt); + break; + + case STM_TRKPT: + if (track == NULL) + { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + break; + } + wpt = NULL; + } + } +} + +static void +stmwpp_rw_init(const char *fname) +{ + fout = gbfopen(fname, "wb", MYNAME); +} + +static void +stmwpp_rw_deinit(void) +{ + gbfclose(fout); +} + +static void +stmwpp_track_hdr(const route_head *track) +{ + track_num++; +} + +static void +stmwpp_track_tlr(const route_head *track) +{ +} + +static void +stmwpp_write_double(const double val) +{ + char buff[64]; + char *c; + + c = buff + snprintf(buff, sizeof(buff), "%3.7f", val); + while (*--c == '0') *c = '\0'; + if (*c == '.') *c = '0'; + gbfprintf(fout, "%s,", buff); +} + +static void +stmwpp_waypt_cb(const waypoint *wpt) +{ + char cdate[16], ctime[16]; + struct tm tm; + + if (track_index != track_num) return; + + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon++; + + snprintf(cdate, sizeof(cdate), "%02d/%02d/%04d", tm.tm_mon, tm.tm_mday, tm.tm_year); + snprintf(ctime, sizeof(ctime), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + + switch(what) + { + case STM_WAYPT: + case STM_RTEPT: + gbfprintf(fout, "WP,D,%s,", wpt->shortname); + break; + + case STM_TRKPT: + gbfprintf(fout, "TP,D,"); + break; + } + stmwpp_write_double(wpt->latitude); + stmwpp_write_double(wpt->longitude); + gbfprintf(fout, "%s,%s", cdate, ctime); + switch(what) + { + case STM_WAYPT: + case STM_RTEPT: + gbfprintf(fout, ".%02d", wpt->centiseconds); + break; + case STM_TRKPT: + gbfprintf(fout, ".%03d", wpt->centiseconds * 10); + break; + } + gbfprintf(fout, ",\r\n"); +} + +static void +stmwpp_data_write(void) +{ + track_num = 0; + if (index_opt != NULL) + track_index = atoi(index_opt); + else + track_index = 1; + + gbfprintf(fout, "Datum,WGS 84,WGS 84,0,0,0,0,0\r\n"); + + switch(global_opts.objective) + { + case wptdata: + what = STM_WAYPT; + track_index = track_num; /* disable filter */ + waypt_disp_all(stmwpp_waypt_cb); + break; + case rtedata: + what = STM_RTEPT; + route_disp_all(stmwpp_track_hdr, stmwpp_track_tlr, stmwpp_waypt_cb); + break; + case trkdata: + what = STM_TRKPT; + track_disp_all(stmwpp_track_hdr, stmwpp_track_tlr, stmwpp_waypt_cb); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } +} + +ff_vecs_t stmwpp_vecs = { + ff_type_file, + FF_CAP_RW_ALL, + stmwpp_rd_init, + stmwpp_rw_init, + stmwpp_rd_deinit, + stmwpp_rw_deinit, + stmwpp_data_read, + stmwpp_data_write, + NULL, + stmwpp_args, + CET_CHARSET_MS_ANSI, 0 +}; diff --git a/strptime.c b/strptime.c index 968934ff6..7d56a1539 100644 --- a/strptime.c +++ b/strptime.c @@ -551,11 +551,13 @@ strptime_internal (rp, fmt, tm, decided, era_cnt) *decided = raw; } #endif - if (!match_string (HERE_AM_STR, rp)) - if (match_string (HERE_PM_STR, rp)) + if (!match_string (HERE_AM_STR, rp)) { + if (match_string (HERE_PM_STR, rp)) { is_pm = 1; - else + } else { return NULL; + } + } break; case 'r': #ifdef _NL_CURRENT diff --git a/style/README.style b/style/README.style deleted file mode 100644 index b191b9bd1..000000000 --- a/style/README.style +++ /dev/null @@ -1,492 +0,0 @@ -GPSBabel XCSV Style File Layout: - -The format of an XCSV style file is quite simple and designed to be easily -implemented by non-programmers to handle "one-off" babel-ization of various -XCSV (whatever separated values) text files. The format and usage of the -various style directives are described below. - -The first and foremost important step is understanding how the config -file is laid out itself. The format is: - -DIRECTIVEVALUE - -Where is a space, tab, spaces, tabs, etc... There should -be *nothing* before the directive. (i.e. not " DIRECTIVE VALUE") - -INTERNAL CONSTANTS: -A few internal constants are defined in the XCSV parser to make the style -file simpler. They may or may not be used and are optional in most cases. -Note that only certain style file directives map these constants. - -STYLE CONSTANT MAPS TO CHAR(s) ---------------------------------------- -COMMA , -COMMASPACE , -SINGLEQUOTE ' -DOUBLEQUOTE " -COLON : -SEMICOLON ; -NEWLINE \n -CR \r -CRNEWLINE \r\n -TAB \t -SPACE -HASH # -PIPE | -WHITESPACE *** SEE WHITESPACE NOTES BELOW *** - -WHITESPACE: -The WHITESPACE constant has special properties. When reading data, -WHITESPACE refers to sequential runs of SPACES and/or TABS. When -writing data, WHITESPACE is always a single SPACE. - -For example, the following line: -SOME_NAME 30.1208 -91.1365 SOME OTHER NAME - -Parses into the following data fields: -SOME_NAME,30.1208,-91.1365,SOME,OTHER,NAME - - -COMMENTS: -Anything after a hash (#) on a line is not parsed. For example: -#THIS ENTIRE LINE IS A COMMENT. -#FIELD LAT_DECIMAL, "", "%f" THIS ENTIRE LINE IS A COMMENT -FIELD LAT_DECIMAL, "", "%f" # ONLY THIS SENTENCE IS A COMMENT. - - - -GLOBAL PROPERTIES OF THE FILE: --------------------------------- -There are a few available directives to describe general traits of the -file being described and not specific data within the file itself. - - o DESCRIPTION: - - This is the description of the file format being described. This text - appears in the help screens and in menus used by the various GUI wrappers. - - o EXTENSION: - - This directive gives the filename extension generally associated with - this file. - -GPSBABEL BEHAVIOR DIRECTIVES: ------------------------------ -There are a few available directives to 'control' some of the internal -processing functions of GPSbabel. - - o SHORTLEN: - - This sets the maximum allowed shortname length when using the internal - shortname synthesizer. - - example: - SHORTLEN 16 # shortnames will be at most 16 characters long. - - - o SHORTWHITE: - - This tells the shortname synthesizer whether or not to allow whitespace - in the synthesized shortnames. Allowed values are zero and one. - - example: - SHORTWHITE 0 # Do not allow whitespace in shortname. - SHORTWHITE 1 # Allow whitespace in shortname. - - -DEFINING THE LAYOUT OF THE FILE: --------------------------------- -The first few directives define the layout the physical file itself: - - o FIELD_DELIMITER: - The field delimiter defines the character(s) that separate the fields in - the rows of data inside the XCSV file. Common field delimiters are commas - and tabs. (referred to as "comma separated values" and "tab separated - values") - - examples: FIELD_DELIMITER COMMA - FIELD_DELIMITER ~ - - The directive FIELD_DELIMITER is parsed for STYLE CONSTANTS as defined in - the table above. - - o RECORD DELIMITER: - The record delimiter defines that character(s) that separate ROWS of - data (FIELDS) in the XCSV file. The most common record delimiters - are NEWLINE and CR (carriage return). - - example: RECORD_DELIMITER NEWLINE - RECORD_DELIMITER | - - The directive RECORD_DELIMITER is parsed for STYLE CONSTANTS as defined - in the table above. - - o BADCHARS: - Bad characters are things that should *never* be written into the XCSV - file as data on output. GPSBabel automatically includes any non-blank - FIELD_DELIMITER and RECORD_DELIMITER characters as BADCHARS by default. - - example: BADCHARS COMMA - BADCHARS ~| - - The directive BADCHARS is parsed for STYLE CONSTANTS as defined in the - table above. - - o PROLOGUE - A prologue is basically constant data that is written to the output - file BEFORE any waypoints are processed. PROLOGUE can be defined - multiple times in the style file, once for each "line" before the data - begins. This is commonly used in XCSV files as a "header" row. - - example: PROLOGUE OziExplorer Waypoint File Version 1.1 - PROLOGUE WGS 84 - * or * - PROLOGUE Symbol,Name,Latitude,Longitude - - o EPILOGUE - An Epilogue is the same as a prologue, except this data is written at - the END of the file. See the examples for PROLOGUE above. - - -DEFINING FIELDS WITHIN THE FILE: -------------------------------- - -A field defines data. There are two different classifications of FIELDS, -IFIELD (file input) and OFIELD (file output). In the absence of any OFIELDS, -IFIELDS are use as both input and output. The existence of OFIELDS is -primarily to allow more flexible mapping of GPSBabel data to output data -(say, for instance, to map the internal GPSBabel "description" variable to -two or more fields on output). For all practical purposes, IFIELDS and -OFIELDS are defined the same way in the style file. - -There are several different types of fields that may be defined. Each field -consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and -a PRINTF CONVERSION (for output). In many cases, not all pieces are used, -but all 3 pieces are required. - -FIELDS should be defined in the style file in the logical order that they -appear in the data, from left to right. This is the order in which they are -parsed from input and written to output. - -The fields used by the XCSV parser are as follows: - - o IGNORE - IGNORE fields are, guess what, ignored on input. Internally, IGNORE - fields are treated as CHARACTER data, and as such, require a printf - conversion for a character array. - - example: IFIELD IGNORE,"","%14.14s" (writes a 14 character blank field) - IFIELD IGNORE,"","%s" (writes a blank field on output) - - o CONSTANT - CONSTANT fields are, of course, constant. They are ignored on input, - however they write CONSTANT data on output. As such, they require a - DEFAULT VALUE and a printf conversion for a character array. - - example: IFIELD CONSTANT,"FFFFFF","%s" (writes "FFFFFF" in the field) - IFIELD CONSTANT,"01/01/70","%s" (a constant date field) - - o INDEX - An INDEX field is used ONLY on output. The INDEX constant defines a field - that, at output, contains the sequence number of the waypoint being - written, starting at 0. An index is managed internally as an INTEGER - and requires an INTEGER printf conversion. An INDEX has one special - property. The DEFAULT VALUE of the index is added to the index - on each iteration (to allow indexes starting at 1, 100, etc..). - - example: IFIELD INDEX,"0","%04d" (Starts counting at zero) - IFIELD INDEX,"","%04d" (Starts counting at zero) - IFIELD INDEX,"1","%04d" (Starts counting at one) - - o SHORTNAME - A SHORTNAME is generally the waypoint name of the data being processed. - SHORTNAME maps directly to the GPSBabel variable ->shortname. A SHORTNAME - is CHARACTER data and requires a character array printf conversion. - - example: IFIELD SHORTNAME,"","%s" (write shortname in the output file) - - o DESCRIPTION - A DESCRIPTION is generally a long description of the waypoint. A - DESCRIPTION maps to the GPSBabel variable ->description and is otherwise - handled exactly like a SHORTNAME. - - example: IFIELD DESCRIPTION,"","%s" (write description in the output file) - - o NOTES - NOTES are generally everything else about a waypoints. NOTES map to the - GPSBabel variable ->notes and is otherwise handled exactly like a - SHORTNAME. - - o URL - URL is a URL for the waypoint. URL maps to the GPSBabel variable - ->url and is otherwise handled exactly like a SHORTNAME. - - example: IFIELD URL,"","%s" (writes the URL in the output file) - - o URL_LINK_TEXT - URL_LINK_TEXT is a textual description of where a URL points. - URL_LINK_TEXT maps to the GPSBabel variable ->url_link_text and - is otherwise handled exactly like a SHORTNAME. - - example: IFIELD URL_LINK_TEXT,"","%s" (writes link text in the output file) - - o ICON_DESCR - ICON_DESCR is a textual description of an icon type for a waypoint. - ICON_DESCR maps to the GPSBabel variable ->icon_desc and is otherwise - handled exactly like a SHORTNAME. - - example: IFIELD ICON_DESCR,"","%s" (writes link text in the output file) - - o LAT_DECIMAL - LAT_DECIMAL defines LATITUDE in DECIMAL format. Note that this is a PURE - signed decimal format (i.e. -91.0000). This data is handled internally as - a DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf conversion. - - example: IFIELD LAT_DECIMAL,"","%f" - - o LON_DECIMAL - See LAT_DECIMAL, except LON_DECIMAL defines LONGITUDE. - - o LAT_INT32DEG - LAT_INT32DEG defines LATITUDE in what I call INT32DEGREES. This value is - a signed LONG INTEGER and requires a LONG INTEGER printf conversion. - - example: IFIELD LAT_INT32DEG,"","%ld" - - o LON_INT32DEG - See LON_INT32DEG except LON_INT32DEG defines LONGITUDE. - - o LAT_DECIMALDIR / LAT_DIRDECIMAL - LAT_DECIMALDIR and LAT_DIRDECIMAL defines LATITUDE in DECIMAL format - with the added bonus of a 'N/S' or 'E/W' direction character. This data - is handled internally as a DOUBLE PRECISION FLOAT and a single - CHARACTER and requires a FLOATING POINT as well as a CHARACTER printf - conversion. The only difference between the two is whether the directional - character appears before (LAT_DIRDECIMAL) or after (LAT_DECIMALDIR) the - decimal number. - - example: IFIELD LAT_DECIMALDIR,"","%f %c" (writes 31.333 N) - example: IFIELD LAT_DIRDECIMAL,"","%c %f" (writes N 31.333) - - o LON_DECIMALDIR / LON_DIRDECIMAL - Same as LAT_DECIMALDIR / LAT_DIRDECIMAL except LON_ defines LONGITUDE. - - o LAT_DIR / LON_DIR - LAT_DIR returns the single character 'N' or 'S' depending on the - hemisphere of the latitude. LON_DIR returns 'E' or 'W' depending on - the hemisphere of the longitude. - - o LAT_HUMAN_READABLE - LAT_HUMAN_READABLE defines LATITUDE in a human-readable format. This - format is probably the most expressive format. It is similar to - LAT_DECIMALDIR in that it requires multiple printf conversions, but it - is far more flexible as to the contents of those conversions. On read, - the printf conversions are ignored and GPSBabel attempts to determine the - latitude and longitude based on what is in the file. - - example: IFIELD LAT_HUMAN_READABLE,"","%c %d %f" (writes N 31 40.000) - example: IFIELD LAT_HUMAN_READABLE,"","%d deg %f min %c" - (writes "31 deg 40.000 min N") - Note that this string will confuse the reading routine due - to the letter "n" in "min" and the letter "e" in "deg." - example: IFIELD LAT_HUMAN_READABLE,"","%d %d %f%c" (writes 31 40 00.000N) - - o LAT_NMEA - Defines the latitude in the format used by the NMEA standard which is - degrees multiplied by 100 plus decimal minutes. - - example: IFIELD LAT_NMEA, "%f", "%08.3f" (writes 3558.322) - - o LON_NMEA - Defines the longitude in the format used by the NMEA standard which is - degrees multiplied by 100 plus decimal minutes. - - example: IFIELD LON_NMEA, "%f", "%010.3f" (writes -08708.082) - - o LON_HUMAN_READABLE - See LAT_HUMAN_READABLE except LON_HUMAN_READABLE defines LONGITUDE. - - o LATLON_HUMAN_READABLE - LATLON_HUMAN_READABLE is like LAT_HUMAN_READABLE and LON_HUMAN_READABLE - except that it reads and writes both latitude and longitude as a single - field. On write, the same format specifier is used for both coordinates. - On read, GPSBabel does exactly the same thing it does for - LAT_HUMAN_READABLE or LON_HUMAN_READABLE. - - example: IFIELD LATLON_HUMAN_READABLE,"","%c %d %f" - (writes "N 31 40.126 W 85 09.62" as a single field) - - o ALT_FEET - ALT_FEET is the position's ALTITUDE in FEET. This value is treated as - a SIGNED DOUBLE PRECISION FLOAT and requires a FLOATING POINT printf - conversion. - - example: IFIELD ALT_FEET,"","%.0f" - - o ALT_METERS - ALT_METERS is identical to ALT_FEET with the exception that the altitude - is in METERS. - - o EXCEL_TIME - EXCEL_TIME is the waypoint's creation time, if any. This is actually - the decimal days since 1/1/1900 and is handled internally as a DOUBLE - PRECISION FLOAT and requires a FLOATING POINT printf conversion. - - example: IFIELD EXCEL_TIME,"","%11.5f" - - o TIMET_TIME - TIMET_TIME is the waypoint's creation time, if any. This is actually - the integer seconds since 1/1/1970 (let's not start the holy war) and - is handled internally as a LONG INTEGER and requires a LONG INTEGER - printf conversion. - - example: IFIELD TIMET_TIME,"","%ld" - - o YYYYMMDD_TIME - YYYYMMDD_TIME is the waypoint's creation time, if any. It's a single - decimal field containing four digits of year, two digits of month, - and two digits of date. Internally it is a LONG INTEGER and thus - requires a LONG INTEGER printf conversion. - - example: IFIELD YYYYMMDD_TIME,"","%ld" - - o GMT_TIME - GMT_TIME is the waypoint's creation time, in UTC time zone. It uses the - strptime conversion format tags. - - example: IFIELD GMT_TIME,"","%m/%d/%Y %I:%M:%D %p" - - Search the web for 'strptime man page' for details strptime, but one - such page can be found at - - http://www.die.net/doc/linux/man/man3/strptime.3.html - - o LOCAL_TIME LOCAL_TIME is the waypoint's creation time, in the local - time zone. It uses strptime conversion format tags. - - example: IFIELD LOCAL_TIME,"","%y-%m-%d" - - o HMSG_TIME - HMSG_TIME parses up to three time parts and am/pm string to add - this value to the previously parsed *_TIME field that contains - only a date. On output, will print the time in UTC. - - example: IFIELD HMSG_TIME,"","%d:%d:%d %s" - - o HMSL_TIME - HMSG_TIME parses up to three time parts and am/pm string to add - this value to the previously parsed *_TIME field that contains - only a date. On output, will print the time in local time. - - example: IFIELD HMSL_TIME,"","%dh%dm" - - o ISO_TIME - ISO_TIME is the waypoint's creation time, in ISO 8601 format, - which include time zone information. - It is expected to be in the format yyyy-mm-ddThh:mm:sszzzzz - where zzzzzz is the local time offset or the character Z - for UTC time. - On output, UTC 'Z' time zone will always be used. - - example: IFIELD ISO_TIME,"","%s" - - o GEOCACHE_DIFF - GEOCACHE_DIFF is valid only for geocaches and represents a DOUBLE - PRECISION FLOAT. A "three and a half star" cache would therefore be "3.5" - - example: IFIELD GEOCACHE_DIFF,"","%3.1f" - - o GEOCACHE_TERR - GEOCACHE_TERR is valid only for geocaches and represents a DOUBLE - PRECISION FLOAT. A "three and a half star" cache would therefore be "3.5" - - example: IFIELD GEOCACHE_TERR,"","%3.1f" - - o GEOCACHE_CONTAINER - GEOCACHE_CONTAINER is valid only for geocaches and is heavily influenced - by the Groundspeak container types. Examples would include "Micro" - and "Virtual". - - example: GEOCACHE_CONTAINER,"","%s" - - o GEOCACHE_TYPE - GEOCACHE_TYPE is valid only for geocaches and is heavily influenced - by the Groundspeak cache types. Examples would include "Event cache" - and "Multi-Cache". - - example: GEOCACHE_TYPE,"","%s" - - o GEOCACHE_PLACER - GEOCACHE_PLACER is a string containing the name of the placer of a - geocache. - - example: GEOCACHE_PLACER,"","%s" - - o GEOCACHE_LAST_FOUND - A long integer in format YYYYMMDD containing the last time this geocache - was found. - - example: GEOCACHE_LAST_FOUND,"","%ld" - - o GEOCACHE_HINT - The hint for this geocache. No additional transformation (such as rot13) - will be performed on this string. - - example: GEOCACHE_HINT,"","%s" - - o PATH_DISTANCE_MILES - PATH_DISTANCE_MILES outputs the total length of the route or track from - the start point to the current point, in miles. This and the altitude - could be used to create an elevation profile. PATH_DISTANCE_MILES is - a DOUBLE PRECISION FLOAT. - PATH_DISTANCE_MILES is not valid as an input field. - PATH_DISTANCE_MILES is only meaningful if the data comes from a track - or a route; waypoint data will generate essentially meaningless output. - - example: PATH_DISTANCE_MILES,"","%f" - - o PATH_DISTANCE_KM - PATH_DISTANCE_KM is like PATH_DISTANCE_MILES except it outputs the - length in kilometers. - - o PATH_SPEED - Speed in meters per second. Gpsbabel does NOT calculate this data, it is - read from the input file if present. - - example: PATH_SPEED,"","%f" - - o PATH_COURSE - Course in degerees. Gpsbabel does NOT calculate this data, it is - read from the input file if present. - - example: PATH_COURSE,"","%f" - - o GPS_HDOP, GPS_VDOP, GPS_PDOP - GPS distorsion of position parameters. Needs float conversion. - - example: GPS_HDOP,"","%f" - - o GPS_SAT - Number of satellites used for determination of the position. Needs - interger conversion. - - example: GPS_SAT,"","%d" - - o GPS_FIX - Type of fix (see GPX spec). Needs string conversion. - - example: GPS_FIX,"","%s" - -EXAMPLES: --------- -For examples on using the XCSV module, please see the *.style files in -the style/ subdirectory of GPSBabel. - -MISCELLANEOUS NOTES: --------------------- - o DEFAULT VALUES - Default values are supported for any output fields that contain pure - character data output such as URL and NOTES. Default values are only - written on output and are not used to supplement missing input. When - using default values your mileage will vary greatly depending on the - input formats used to populate waypoint data. diff --git a/style/arc.style b/style/arc.style index 82fcbc9bc..85a102d29 100644 --- a/style/arc.style +++ b/style/arc.style @@ -17,5 +17,8 @@ RECORD_DELIMITER NEWLINE # # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: # -IFIELD LAT_DECIMAL, "", "%08.5f" -IFIELD LON_DECIMAL, "", "%08.5f" +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD LON_HUMAN_READABLE, "", "%08.5f" + +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD LON_DECIMAL, "", "%08.5f" diff --git a/style/cambridge.style b/style/cambridge.style new file mode 100644 index 000000000..f0e2bce12 --- /dev/null +++ b/style/cambridge.style @@ -0,0 +1,18 @@ +DESCRIPTION Cambridge/Winpilot glider software +SHORTLEN 8 +EXTENSION dat +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +IFIELD INDEX,"1","%d" +IFIELD LAT_HUMAN_READABLE,"","%d:%06.3f%c" +IFIELD LON_HUMAN_READABLE,"","%03d:%06.3f%c" +IFIELD ALT_METERS,"","%3.0fM" +IFIELD CONSTANT,"","T" +IFIELD SHORTNAME,"","%s" +IFIELD DESCRIPTION,"","%s" diff --git a/style/cup.style b/style/cup.style new file mode 100644 index 000000000..0a5c225aa --- /dev/null +++ b/style/cup.style @@ -0,0 +1,46 @@ +# +# (c) 2006, Robert Lipe, based on sample files by Krzysztof Wojtas +# Reference info: http://www.seeyou.ws/thankyou.php?fname=cup_format.pdf +# + +DESCRIPTION See You flight analysis data +SHORTLEN 8 +EXTENSION cup +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS ," +PROLOGUE name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc +EPILOGUE -----Related Tasks----- + + +IFIELD SHORTNAME,"", ""%s"" +IFIELD SHORTNAME,"", "%s" +IFIELD CONSTANT,"", "" +IFIELD LAT_NMEA, "%f", "%08.3f", "absolute" +IFIELD LON_NMEA, "%f", "%09.3f", "absolute" +IFIELD ALT_METERS,"", "%dm" +IFIELD CONSTANT,"", "1" +IFIELD CONSTANT,"", "" +IFIELD CONSTANT,"", "" +IFIELD CONSTANT,"", "" +IFIELD DESCRIPTION,"", ""%s"" + +OFIELD SHORTNAME,"", ""%s"" +OFIELD SHORTNAME,"", "%s" +OFIELD CONSTANT,"", "" +OFIELD LAT_NMEA, "%f", "%08.3f", "absolute" +OFIELD LAT_DIR, "", "%c", "no_delim_before" +OFIELD LON_NMEA, "%f", "%09.3f", "absolute" +OFIELD LON_DIR, "", "%c", "no_delim_before" +OFIELD ALT_METERS,"", "%3.1fm" +OFIELD CONSTANT,"", "1" +OFIELD CONSTANT,"", "" +OFIELD CONSTANT,"", "" +OFIELD CONSTANT,"", "" +OFIELD DESCRIPTION,"", ""%s"" + + diff --git a/style/custom.style b/style/custom.style index d3776aaf1..ffdb341a0 100644 --- a/style/custom.style +++ b/style/custom.style @@ -24,7 +24,7 @@ PROLOGUE Prologue Line 2 # # INDIVIDUAL DATA FIELDS: # -IFIELD CONSTANT, "", "CONSTANT" +IFIELD CONSTANT, "CONSTANT", "%s" IFIELD INDEX, "", "%d" IFIELD LAT_DECIMAL, "", "%f" IFIELD LAT_DIR, "", "%c" diff --git a/style/garmin301.style b/style/garmin301.style new file mode 100644 index 000000000..57e199ad8 --- /dev/null +++ b/style/garmin301.style @@ -0,0 +1,34 @@ +# gpsbabel XCSV style file +# +# Format: Garmin 301 Position + Heartrate data +# Author: Jeff Kalikstein +# Date: 08/29/2005 +# + +DESCRIPTION Garmin 301 Custom position and heartrate + +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +#FORMAT_TYPE INTERNAL + +# +# HEADER STUFF: +# +PROLOGUE Garmin 301 data __FILE__ +PROLOGUE Timestamp,Latitude, Longitude, Altitude(ft), heart rate +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD TIMET_TIME,"","%ld" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LON_DECIMAL, "", "%f" +IFIELD ALT_FEET, "", "%fF" +IFIELD HEART_RATE,""," %d" # beats per minute + + +# EPILOGUE: +#EPILOGUE Epilogue Line 1 +#EPILOGUE Epilogue Line 2 diff --git a/style/garmin_poi.style b/style/garmin_poi.style new file mode 100644 index 000000000..e15b35bf3 --- /dev/null +++ b/style/garmin_poi.style @@ -0,0 +1,34 @@ +# gpsbabel XCSV style file +# +# Format: Garmin POI +# Author: Robert Lipe +# Date: 10/07/2005 +# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204 +# +DESCRIPTION Garmin POI database +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA +SHORTLEN 24 +# PROLOGUE Longitude,Latitude,Name, comment + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LON_HUMAN_READABLE, "", "%08.5f" +IFIELD LAT_HUMAN_READABLE, "", "%08.5f" +IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", "%s" + +OFIELD LON_DECIMAL, "", "%08.5f" +OFIELD LAT_DECIMAL, "", "%08.5f" +OFIELD SHORTNAME, "", "%-.24s" +OFIELD GEOCACHE_TYPE, "", " %-.4s", "no_delim_before,optional" +OFIELD GEOCACHE_CONTAINER, "", "/%-.4s ", "no_delim_before,optional" +OFIELD GEOCACHE_DIFF, "", "(%3.1f", "no_delim_before,optional" +OFIELD GEOCACHE_TERR, "", "/%3.1f)", "no_delim_before,optional" +OFIELD DESCRIPTION, "", "%-.50s" diff --git a/style/geonet.style b/style/geonet.style new file mode 100644 index 000000000..7b7d3a15c --- /dev/null +++ b/style/geonet.style @@ -0,0 +1,49 @@ +# gpsbabel XCSV style file +# +# Format: GEOnet Names Server (GNS) (http://earth-info.nga.mil/gns/html/cntry_files.html) +# Author: Olaf Klein +# Date: 08/20/2002 +# + +DESCRIPTION GEOnet Names Server (GNS) +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# + +FIELD_DELIMITER TAB +RECORD_DELIMITER CRNEWLINE +BADCHARS TAB +ENCODING UTF-8 + +PROLOGUE RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE + +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD IGNORE, "", "%s" # RC ( http://earth-info.nga.mil/gns/html/gis_contryfiles.html ) +IFIELD IGNORE, "", "%s" # UFI +IFIELD IGNORE, "", "%s" # UNI +IFIELD LAT_DECIMAL, "", "%03.7f" # LAT +IFIELD LON_DECIMAL, "", "%03.7f" # LONG +IFIELD IGNORE, "", "%s" # DMS_LAT +IFIELD IGNORE, "", "%s" # DMS_LONG +IFIELD IGNORE, "", "%s" # UTM +IFIELD IGNORE, "", "%s" # JOG +IFIELD IGNORE, "", "%s" # FC +IFIELD IGNORE, "", "%s" # DSG +IFIELD IGNORE, "", "%s" # PC +IFIELD IGNORE, "", "%s" # CC1 +IFIELD IGNORE, "", "%s" # ADM1 +IFIELD IGNORE, "", "%s" # ADM2 +IFIELD IGNORE, "", "%s" # DIM +IFIELD IGNORE, "", "%s" # CC2 +IFIELD IGNORE, "", "%s" # NT +IFIELD IGNORE, "", "%s" # LC +IFIELD IGNORE, "", "%s" # SHORT_FORM +IFIELD IGNORE, "", "%s" # GENERIC +IFIELD SHORTNAME, "", "%s" # SHORT_NAME +IFIELD DESCRIPTION, "", "%s" # FULL_NAME +IFIELD IGNORE, "", "%s" # FULL_NAME_ND +IFIELD IGNORE, "", "%s" # MOD_DATE diff --git a/style/gpsdrivetrack.style b/style/gpsdrivetrack.style index e7a47ffcd..6bc036a5a 100644 --- a/style/gpsdrivetrack.style +++ b/style/gpsdrivetrack.style @@ -21,7 +21,7 @@ SHORTWHITE 0 # # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: -OFIELD LAT_DECIMAL, "", "%10.6f" -OFIELD LON_DECIMAL, "", "%10.6f" -OFIELD ALT_METERS, "", "%10.0f" -OFIELD GMT_TIME, "", "%a %b %d %T %Y" +IFIELD LAT_DECIMAL, "", "%10.6f" +IFIELD LON_DECIMAL, "", "%10.6f" +IFIELD ALT_METERS, "", "%10.0f" +IFIELD GMT_TIME, "", "%a %b %d %T %Y" diff --git a/style/ktf2.style b/style/ktf2.style new file mode 100644 index 000000000..43c8cd1b9 --- /dev/null +++ b/style/ktf2.style @@ -0,0 +1,35 @@ +# gpsbabel XCSV style file +# +# Format: Kartex KTF 2.0 Degrees with decimals +# Author: Harald Nordius +# Date: 4/13 2006 +# +# +DESCRIPTION Kartex 5 Track File +EXTENSION ktf +SHORTLEN 10 +SHORTWHITE 1 +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER CRNEWLINE +# +# +# FILE HEADER +# +PROLOGUE //Kartex Track File created by GPSBabel +PROLOGUE &KTF 2.0,sweref 99 lat long,0 +# +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD CONSTANT, %, "%s" +IFIELD INDEX, "", "%d" +IFIELD LATLON_HUMAN_READABLE, "", "%c%f°" +IFIELD ALT_METERS, "", "%.2f" +IFIELD GMT_TIME, "", "%Y-%m-%d %H:%M:%S" +IFIELD IGNORE, "", "%s" #Empty field +IFIELD IGNORE, "", "%s" #Empty field +IFIELD CONSTANT, "$", "%s" diff --git a/style/kwf2.style b/style/kwf2.style new file mode 100644 index 000000000..77fab79d4 --- /dev/null +++ b/style/kwf2.style @@ -0,0 +1,38 @@ +# gpsbabel XCSV style file +# +# Format: Kartex KWF 2.0 Degrees with decimals +# Author: Harald Nordius +# Date: 12/08 2004 +# +# +DESCRIPTION Kartex 5 Waypoint File +EXTENSION kwf +SHORTLEN 10 +SHORTWHITE 1 +# +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER CRNEWLINE +ENCODING CP1252 +# +# +# FILE HEADER +# +PROLOGUE //Kartex Waypoint File created by GPSBabel +PROLOGUE &KWF 2.0,sweref 99 lat long,0 +# +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD CONSTANT, \#, "%s" +IFIELD INDEX,"","%d" +IFIELD SHORTNAME,"","%s" +IFIELD LATLON_HUMAN_READABLE,"","%c%f°" +IFIELD ALT_METERS,"","%.2f" +IFIELD IGNORE, "","%s" #Empty field +IFIELD IGNORE, "","%s" #Empty field +IFIELD CONSTANT, "0","%s" #Waypoint symbol code +IFIELD DESCRIPTION, "", "%s" +IFIELD CONSTANT, "$", "%s" diff --git a/style/mxf.style b/style/mxf.style index e0229b792..08d35e7d6 100644 --- a/style/mxf.style +++ b/style/mxf.style @@ -17,15 +17,15 @@ EXTENSION mxf # FIELD_DELIMITER COMMASPACE RECORD_DELIMITER NEWLINE -BADCHARS ", +BADCHARS ," # # INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: # IFIELD LAT_DECIMAL, "", "%08.5f" IFIELD LON_DECIMAL, "", "%08.5f" -IFIELD DESCRIPTION, "", "%s" -IFIELD SHORTNAME, "", "%s" +IFIELD DESCRIPTION, "", ""%s"" +IFIELD SHORTNAME, "", ""%s"" IFIELD IGNORE, "", "%s" IFIELD CONSTANT, "ff0000", "%s" # COLOR IFIELD CONSTANT, "47", "%s" # ICON diff --git a/style/openoffice.style b/style/openoffice.style index ea42b7f9d..9ba62534a 100644 --- a/style/openoffice.style +++ b/style/openoffice.style @@ -1,12 +1,12 @@ # gpsbabel XCSV style file # -# Format: Tab delimitered csv useful for OpenOffice, Ploticus etc. +# Format: Tab delimited useful for OpenOffice, Ploticus etc. # Author: Tobias Minich # Date: 07/18/2005 # # -DESCRIPTION Tab delimitered csv useful for OpenOffice, Ploticus etc. +DESCRIPTION Tab delimited fields useful for OpenOffice, Ploticus etc. # FILE LAYOUT DEFINITIIONS: # diff --git a/style/s_and_t.style b/style/s_and_t.style index a9c685dd5..364615485 100644 --- a/style/s_and_t.style +++ b/style/s_and_t.style @@ -12,7 +12,7 @@ # GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache # -DESCRIPTION Microsoft Streets and Trips 2002-2005 +DESCRIPTION Microsoft Streets and Trips 2002-2006 EXTENSION txt diff --git a/style/sportsim.style b/style/sportsim.style new file mode 100644 index 000000000..7acae5591 --- /dev/null +++ b/style/sportsim.style @@ -0,0 +1,32 @@ +# gpsbabel XCSV style file +# +# Format: Sportsim track files +# Author: Olaf Klein +# Date: 07/05/2006 +# +DESCRIPTION Sportsim track files (part of zipped .ssz files) +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER SEMICOLON +RECORD_DELIMITER CRNEWLINE +BADCHARS TAB + +# +# FILE HEADER +# +PROLOGUE SportsimVersion:01 +PROLOGUE \#Sportsim TrackFile + +# +# INDIVIDUAL DATA FIELDS: +# +IFIELD INDEX, "", "%05d" +IFIELD CONSTANT, "0", "%s" +IFIELD LAT_DECIMAL, "", "%f" +IFIELD LON_DECIMAL, "", "%f" +IFIELD ALT_FEET, "", "%.f" +IFIELD TIMET_TIME, "", "%ld" +IFIELD CONSTANT, ";", "%s" diff --git a/style/xmap2006.style b/style/xmap2006.style new file mode 100644 index 000000000..7b4ce2380 --- /dev/null +++ b/style/xmap2006.style @@ -0,0 +1,37 @@ +# gpsbabel XCSV style file +# +# Format: DeLorme Xmap/Street Atlas Handheld 2006 Conduit +# Author: Pasha Phares +# Date: 5/5/2006 +# +# Amazingly, 2006 won't read the "COMMASPACE" that we used in +# in Xmap prior to this and versions before 2006 won't read files +# separated by only a comma. +# + +DESCRIPTION DeLorme XMap/SAHH 2006 Native .TXT +EXTENSION txt + +# +# FILE LAYOUT DEFINITIIONS: +# +FIELD_DELIMITER COMMA +RECORD_DELIMITER NEWLINE +BADCHARS COMMA + +PROLOGUE BEGIN SYMBOL +EPILOGUE END +# +# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE: +# +IFIELD LAT_HUMAN_READABLE, "", "%.12g" +IFIELD LON_HUMAN_READABLE, "", "%.12g" +IFIELD SHORTNAME, "", "%s" + +OFIELD LAT_DECIMAL, "", "%.12g" +OFIELD LON_DECIMAL, "", "%.12g" +OFIELD SHORTNAME, "", "%s" + + + + diff --git a/tef_xml.c b/tef_xml.c index 85308dbb4..3112d5fc5 100644 --- a/tef_xml.c +++ b/tef_xml.c @@ -2,7 +2,7 @@ Support for XML based "TourExchangeFormat", found in Map & Guide Motorrad-Tourenplaner 2005/06 - Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org Based on kml.c, Keyhole "kml" format. Copyright (C) 2005 Robert Lipe, robertlipe@usa.net @@ -26,28 +26,23 @@ #include "defs.h" #include "xmlgeneric.h" -static char *deficon = NULL; - static waypoint *wpt_tmp = NULL; static int item_count = -1; static int waypoints = 0; static route_head *route = NULL; -FILE *fd; -FILE *ofd; - static char *routevia = NULL; static arglist_t tef_xml_args[] = { - {"routevia", &routevia, "Include only via stations in route", NULL, ARGTYPE_BOOL}, - {0, 0, 0, 0 } + {"routevia", &routevia, "Include only via stations in route", NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR }; #define MYNAME "TourExchangeFormat" -#if NO_EXPAT +#if ! HAVE_LIBEXPAT void tef_xml_rd_init(const char *fname) { @@ -304,5 +299,6 @@ ff_vecs_t tef_xml_vecs = { tef_xml_read, NULL, NULL, - tef_xml_args + tef_xml_args, + CET_CHARSET_UTF8, 1 }; diff --git a/testc b/testc index 38093cbd2..aa9d64a9e 100644 --- a/testc +++ b/testc @@ -10,6 +10,7 @@ TMPD=/tmp/babeltest.$$ GB="./gpsbabel" +GB="valgrind -q ./gpsbabel" mkdir $TMPD diff --git a/testo b/testo index 19832b75f..9e09220a7 100644 --- a/testo +++ b/testo @@ -1,9 +1,21 @@ +#!/bin/sh + GPSBABEL_FREEZE_TIME=y export GPSBABEL_FREEZE_TIME +# Turn on GNU libc instrumentation. +MALLOC_CHECK_=2 +export MALLOC_CHECK_ + PNAME=${PNAME:-./gpsbabel} DIFF=${DIFF:-diff} -OD=${OD:-od -Ax -txC -v} +REFERENCE=reference +# OD=${OD:-od -Ax -txC -v} +if [ -x /usr/bin/hexdump ] ; then + OD=${OD:-hexdump -v -C} +else + OD=${OD:-od -Ax -txC -v} +fi TMPDIR=/tmp/gpsbabel.$$ mkdir -p $TMPDIR @@ -36,35 +48,56 @@ sort_and_compare() compare $TMPDIR/s1 $TMPDIR/s2 } - +# Some formats are just too boring to test. The ones that +# are xcsv include +# garmin301 +# garmin_poi +# gpsdrivetrack +# nima +# mapconverter +# geonet +# saplus +# s_and_t +# xmap2006 +# cambridge +# cup + # Geocaching .loc rm -f ${TMPDIR}/gl.loc -${PNAME} -i geo -f geocaching.loc -o geo -F ${TMPDIR}/gl.loc -compare ${TMPDIR}/gl.loc reference +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/gl.loc +compare ${TMPDIR}/gl.loc ${REFERENCE} # GPSUtil rm -f ${TMPDIR}/gu.wpt ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx -${PNAME} -i geo -f geocaching.loc -o gpsutil -F ${TMPDIR}/gu.wpt -compare ${TMPDIR}/gu.wpt reference +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpsutil -F ${TMPDIR}/gu.wpt +compare ${TMPDIR}/gu.wpt ${REFERENCE} ${PNAME} -i gpsutil -f ${TMPDIR}/gu.wpt -o gpx -F ${TMPDIR}/1.gpx -${PNAME} -i gpsutil -f reference/gu.wpt -o gpx -F ${TMPDIR}/2.gpx +${PNAME} -i gpsutil -f ${REFERENCE}/gu.wpt -o gpx -F ${TMPDIR}/2.gpx compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx # GPSman rm -f ${TMPDIR}/gm.gm ${TMPDIR}/gm.gm+ -${PNAME} -i geo -f geocaching.loc -o gpsman -F ${TMPDIR}/gm.gm +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpsman -F ${TMPDIR}/gm.gm ${PNAME} -i gpsman -f ${TMPDIR}/gm.gm -o gpsutil -F ${TMPDIR}/gm.gm+ compare ${TMPDIR}/gm.gm+ ${TMPDIR}/gu.wpt # GPX rm -f ${TMPDIR}/gl.gpx ${TMPDIR}/gpx.gpx -${PNAME} -i geo -f geocaching.loc -o gpx -F ${TMPDIR}/gl.gpx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpx -F ${TMPDIR}/gl.gpx ${PNAME} -i gpx -f ${TMPDIR}/gl.gpx -o gpsutil -F ${TMPDIR}/gpx.gpx compare ${TMPDIR}/gpx.gpx ${TMPDIR}/gu.wpt +# GTM +rm -f ${TMPDIR}/gl.gpx ${TMPDIR}/gpx.gpx +${PNAME} -i gtm -f ${REFERENCE}/sample.gtm -o gpx -F ${TMPDIR}/gtm1.gpx +${PNAME} -i gpx -f ${TMPDIR}/gtm1.gpx -o gtm -F ${TMPDIR}/gtm.gtm +${PNAME} -i gtm -f ${TMPDIR}/gtm.gtm -o gpx -F ${TMPDIR}/gtm2.gpx +compare ${TMPDIR}/gtm1.gpx ${TMPDIR}/gtm2.gpx +bincompare ${TMPDIR}/gtm.gtm ${REFERENCE}/sample.gtm + # Magellan Mapsend rm -f ${TMPDIR}/mm.mapsend ${TMPDIR}/mm.gps -${PNAME} -i geo -f geocaching.loc -o mapsend -F ${TMPDIR}/mm.mapsend +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o mapsend -F ${TMPDIR}/mm.mapsend ${PNAME} -i mapsend -f ${TMPDIR}/mm.mapsend -o gpsutil -F ${TMPDIR}/mm.gps compare ${TMPDIR}/mm.gps ${TMPDIR}/gu.wpt @@ -76,7 +109,7 @@ compare ${TMPDIR}/mm.gps ${TMPDIR}/gu.wpt # so we simply test we can write it, and then read it and write it and # get an identical file back. rm -f ${TMPDIR}/tiger -${PNAME} -i geo -f geocaching.loc -o tiger -F ${TMPDIR}/tiger +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o tiger -F ${TMPDIR}/tiger ${PNAME} -i tiger -f ${TMPDIR}/tiger -o tiger -F ${TMPDIR}/tiger2 compare ${TMPDIR}/tiger ${TMPDIR}/tiger2 @@ -88,23 +121,23 @@ compare ${TMPDIR}/tiger ${TMPDIR}/tiger2 rm -f ${TMPDIR}/lowrance1.usr rm -f ${TMPDIR}/enchilada1.usr rm -f ${TMPDIR}/enchilada.gpx -${PNAME} -i geo -f geocaching.loc -o lowranceusr -F ${TMPDIR}/lowrance1.usr -bincompare ${TMPDIR}/lowrance1.usr reference/lowrance.usr +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o lowranceusr -F ${TMPDIR}/lowrance1.usr +bincompare ${TMPDIR}/lowrance1.usr ${REFERENCE}/lowrance.usr ${PNAME} -i lowranceusr -f ${TMPDIR}/lowrance1.usr -o lowranceusr -F ${TMPDIR}/lowrance1.usr # And because of the FP rounding, we can't even read our file, write it back # and get the same data. Sigh. -# bincompare reference/lowrance.usr ${TMPDIR}/lowrance1.usr -${PNAME} -i lowranceusr -f reference/all.usr -o gpx -F ${TMPDIR}/enchilada.gpx +# bincompare ${REFERENCE}/lowrance.usr ${TMPDIR}/lowrance1.usr +${PNAME} -i lowranceusr -f ${REFERENCE}/all.usr -o gpx -F ${TMPDIR}/enchilada.gpx ${PNAME} -i gpx -f ${TMPDIR}/enchilada.gpx -o lowranceusr -F ${TMPDIR}/enchilada1.usr -bincompare ${TMPDIR}/enchilada1.usr reference/enchilada.usr +bincompare ${TMPDIR}/enchilada1.usr ${REFERENCE}/enchilada.usr # Don't convert icons as waypts -${PNAME} -i lowranceusr,ignoreicons -f reference/all.usr -o gpx -F ${TMPDIR}/enchilada.gpx +${PNAME} -i lowranceusr,ignoreicons -f ${REFERENCE}/all.usr -o gpx -F ${TMPDIR}/enchilada.gpx ${PNAME} -i gpx -f ${TMPDIR}/enchilada.gpx -o lowranceusr -F ${TMPDIR}/enchilada1.usr -bincompare ${TMPDIR}/enchilada1.usr reference/ignoreicons.usr +bincompare ${TMPDIR}/enchilada1.usr ${REFERENCE}/ignoreicons.usr # CSV (Comma separated value) data. -${PNAME} -i geo -f geocaching.loc -o csv -F ${TMPDIR}/csv.csv +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o csv -F ${TMPDIR}/csv.csv ${PNAME} -i csv -f ${TMPDIR}/csv.csv -o csv -F ${TMPDIR}/csv2.csv compare ${TMPDIR}/csv2.csv ${TMPDIR}/csv.csv @@ -112,48 +145,66 @@ compare ${TMPDIR}/csv2.csv ${TMPDIR}/csv.csv # Delorme TopoUSA 4 is a CSV strain. # rm -f ${TMPDIR}/xmap-1.gpx ${TMPDIR}/xmap-2.gpx ${TMPDIR}/xmap -${PNAME} -i xmap -f reference/xmap -o xmap -F ${TMPDIR}/xmap -${PNAME} -i xmap -f reference/xmap -o gpx -F ${TMPDIR}/xmap-1.gpx +${PNAME} -i xmap -f ${REFERENCE}/xmap -o xmap -F ${TMPDIR}/xmap +${PNAME} -i xmap -f ${REFERENCE}/xmap -o gpx -F ${TMPDIR}/xmap-1.gpx ${PNAME} -i xmap -f ${TMPDIR}/xmap -o gpx -F ${TMPDIR}/xmap-2.gpx compare ${TMPDIR}/xmap-1.gpx ${TMPDIR}/xmap-2.gpx -compare reference/xmap ${TMPDIR}/xmap +compare ${REFERENCE}/xmap ${TMPDIR}/xmap # PCX (Garmin mapsource import) file format rm -f ${TMPDIR}/mm.pcx ${TMPDIR}/pcx.gps -${PNAME} -i geo -f geocaching.loc -o pcx -F ${TMPDIR}/mm.pcx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o pcx -F ${TMPDIR}/mm.pcx ${PNAME} -i pcx -f ${TMPDIR}/mm.pcx -o gpsutil -F ${TMPDIR}/pcx.gps compare ${TMPDIR}/mm.gps ${TMPDIR}/gu.wpt +${PNAME} -t -i gpx -f ${REFERENCE}/track/tracks.gpx -o pcx -F ${TMPDIR}/pcx.trk +${PNAME} -t -i pcx -f ${REFERENCE}/track/pcx.trk -o pcx -F ${TMPDIR}/pcx2.trk +compare ${TMPDIR}/pcx.trk ${TMPDIR}/pcx2.trk +# # Magellan file format -${PNAME} -i magellan -f reference/magfile -o magellan -F ${TMPDIR}/magfile -compare ${TMPDIR}/magfile reference/magfile +# +${PNAME} -i magellan -f ${REFERENCE}/magfile -o magellan -F ${TMPDIR}/magfile +compare ${TMPDIR}/magfile ${REFERENCE}/magfile + +# +# Magellanx is just like, but with longer names. (which this admittedly +# doesn't actually exercise...) +# +${PNAME} -i magellan -f ${REFERENCE}/magfile -o magellanx -F ${TMPDIR}/magfile2 +compare ${TMPDIR}/magfile2 ${REFERENCE}/magfile + +# Magellanx routes, however, have an extra 'name' field in them. +${PNAME} -r -i magellanx -f ${REFERENCE}/route/magexplorist.rte -o magellanx -F ${TMPDIR}/magxfile.rte +${PNAME} -r -i magellanx -f ${TMPDIR}/magxfile.rte -o magellanx -F ${TMPDIR}/magxfile2.rte +compare ${TMPDIR}/magxfile2.rte ${REFERENCE}/route/magexplorist.rte + # Navitrak DNA marker format -${PNAME} -i dna -f reference/dnatest.txt -o dna -F ${TMPDIR}/dnatest.txt -compare ${TMPDIR}/dnatest.txt reference/dnatest.txt +${PNAME} -i dna -f ${REFERENCE}/dnatest.txt -o dna -F ${TMPDIR}/dnatest.txt +compare ${TMPDIR}/dnatest.txt ${REFERENCE}/dnatest.txt # PSP (PocketStreets 2002 Pushpin (.PSP)) file format. Use mxf as an # intermediate format to avoid binary FP anomalies on compareerent platforms. rm -f ${TMPDIR}/psp.mxf ${TMPDIR}/mxf.psp -${PNAME} -i psp -f reference/ps.psp -o mxf -F ${TMPDIR}/psp.mxf -${PNAME} -i geo -f geocaching.loc -o mxf -F ${TMPDIR}/mxf.psp +${PNAME} -i psp -f ${REFERENCE}/ps.psp -o mxf -F ${TMPDIR}/psp.mxf +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o mxf -F ${TMPDIR}/mxf.psp compare ${TMPDIR}/psp.mxf ${TMPDIR}/mxf.psp -${PNAME} -i psp -f reference/ps.psp -o gpx -F ${TMPDIR}/psp1.gpx -${PNAME} -i psp -f reference/ps.psp -o psp -F ${TMPDIR}/xxx.psp +${PNAME} -i psp -f ${REFERENCE}/ps.psp -o gpx -F ${TMPDIR}/psp1.gpx +${PNAME} -i psp -f ${REFERENCE}/ps.psp -o psp -F ${TMPDIR}/xxx.psp ${PNAME} -i psp -f ${TMPDIR}/xxx.psp -o gpx -F ${TMPDIR}/psp2.gpx compare ${TMPDIR}/psp1.gpx ${TMPDIR}/psp2.gpx # MXF (Maptech Exchange Format) file format rm -f ${TMPDIR}/mx.mxf ${TMPDIR}/mxf.mxf -${PNAME} -i mxf -f reference/mxf.mxf -o mxf -F ${TMPDIR}/mx.mxf +${PNAME} -i mxf -f ${REFERENCE}/mxf.mxf -o mxf -F ${TMPDIR}/mx.mxf ${PNAME} -i mxf -f ${TMPDIR}/mx.mxf -o mxf -F ${TMPDIR}/mxf.mxf -compare ${TMPDIR}/mxf.mxf reference +compare ${TMPDIR}/mxf.mxf ${REFERENCE} # tmpro (TopoMapPro Places) file format rm -f ${TMPDIR}/topomappro.txt ${TMPDIR}/mxf.mxf -${PNAME} -i tmpro -f reference/topomappro.txt -o tmpro -F ${TMPDIR}/tmp.txt +${PNAME} -i tmpro -f ${REFERENCE}/topomappro.txt -o tmpro -F ${TMPDIR}/tmp.txt ${PNAME} -i tmpro -f ${TMPDIR}/tmp.txt -o tmpro -F ${TMPDIR}/topomappro.txt -compare ${TMPDIR}/topomappro.txt reference +compare ${TMPDIR}/topomappro.txt ${REFERENCE} # TPG (NG Topo!) file format # This is hard to test as the datum conversions create minute @@ -161,24 +212,46 @@ compare ${TMPDIR}/topomappro.txt reference # against a format that rounds higher than we care to compare # for binary data. rm -f ${TMPDIR}/topo.mxf ${TMPDIR}/tpg.mxf ${TMPDIR}/geo.tpg -${PNAME} -i geo -f geocaching.loc -o tpg -F ${TMPDIR}/geo.tpg +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o tpg -F ${TMPDIR}/geo.tpg ${PNAME} -i tpg -f ${TMPDIR}/geo.tpg -o mxf -F ${TMPDIR}/tpg.mxf -${PNAME} -i tpg -f reference/tpg.tpg -o mxf -F ${TMPDIR}/topo.mxf +${PNAME} -i tpg -f ${REFERENCE}/tpg.tpg -o mxf -F ${TMPDIR}/topo.mxf compare ${TMPDIR}/tpg.mxf ${TMPDIR}/topo.mxf +# TPO (NG Topo!) file format +# This is hard to test as the datum conversions create minute +# inconsistencies in the coordinates. We have four reference files: +# tpo-sample1.tpo, tpo-sample1.gpx, tpo-sample2.gpx, and +# tpo-sample2.tpo. These are used to check the conversion to/from +# TPO format. +# +# Version 2.x tests +rm -f ${TMPDIR}/tpo-sample1.gpx ${TMPDIR}/tpo-sample2.tpo +${PNAME} -t -i tpo2 -f reference/track/tpo-sample1.tpo -o gpx -F ${TMPDIR}/tpo-sample1.gpx +compare ${TMPDIR}/tpo-sample1.gpx reference/track/tpo-sample1.gpx +#${PNAME} -t -i gpx -f reference/track/tpo-sample2.gpx -o tpo2 -F ${TMPDIR}/tpo-sample2.tpo +#bincompare ${TMPDIR}/tpo-sample2.tpo reference/track/tpo-sample2.tpo +# +# Version 3.x tests. Remove the timestamp from the generated file +# so that the compare will succeed. +rm -f ${TMPDIR}/tpo-sample3.gpx ${TMPDIR}/tpo-sample3.gpx2 +${PNAME} -t -r -w -i tpo3 -f reference/tpo-sample3.tpo -o gpx -F ${TMPDIR}/tpo-sample3.gpx +# Remove the timestamp +grep -v time <${TMPDIR}/tpo-sample3.gpx >${TMPDIR}/tpo-sample3.gpx2 +compare ${TMPDIR}/tpo-sample3.gpx2 reference/tpo-sample3.gpx + # OZI (OziExplorer 1.1) file format rm -f ${TMPDIR}/oz.wpt ${TMPDIR}/ozi.wpt -${PNAME} -i ozi -f reference/ozi.wpt -o ozi -F ${TMPDIR}/oz.wpt +${PNAME} -i ozi -f ${REFERENCE}/ozi.wpt -o ozi -F ${TMPDIR}/oz.wpt ${PNAME} -i ozi -f ${TMPDIR}/oz.wpt -o ozi -F ${TMPDIR}/ozi.wpt -compare ${TMPDIR}/ozi.wpt reference +compare ${TMPDIR}/ozi.wpt ${REFERENCE} # Holux support is a little funky to test. Becuase it loses precision, # if we convert it to another format, we lose accuracy (rounding) in the # coords, so converting it so something else and comparing it never works. # So we verify that we can read the reference and write it and get an # identical reference. -${PNAME} -i holux -f reference/paris.wpo -o holux -F ${TMPDIR}/paris.wpo -# compare reference/paris.wpo ${TMPDIR}/paris.wpo +${PNAME} -i holux -f ${REFERENCE}/paris.wpo -o holux -F ${TMPDIR}/paris.wpo +# compare ${REFERENCE}/paris.wpo ${TMPDIR}/paris.wpo # Magellan NAV Companion for PalmOS # This format is hard to test, because each record and the database itself @@ -191,15 +264,15 @@ ${PNAME} -i holux -f reference/paris.wpo -o holux -F ${TMPDIR}/paris.wpo # successfully test for some endianness errors that might otherwise go # unnoticed. rm -f ${TMPDIR}/magnav.pdb ${TMPDIR}/magnav.gpu ${TMPDIR}/magnavt.gpu -${PNAME} -i geo -f geocaching.loc -o magnav -F ${TMPDIR}/magnav.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o magnav -F ${TMPDIR}/magnav.pdb ${PNAME} -i magnav -f ${TMPDIR}/magnav.pdb -o gpsutil -F ${TMPDIR}/magnav.gpu -${PNAME} -i magnav -f reference/magnav.pdb -o gpsutil -F ${TMPDIR}/magnavt.gpu +${PNAME} -i magnav -f ${REFERENCE}/magnav.pdb -o gpsutil -F ${TMPDIR}/magnavt.gpu compare ${TMPDIR}/magnavt.gpu ${TMPDIR}/magnav.gpu -compare reference/gu.wpt ${TMPDIR}/magnav.gpu +compare ${REFERENCE}/gu.wpt ${TMPDIR}/magnav.gpu rm -f ${TMPDIR}/magnav.pdb -${PNAME} -i geo -f geocaching.loc -o magnav -F ${TMPDIR}/magnav.pdb -bincompare ${TMPDIR}/magnav.pdb reference/magnav.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o magnav -F ${TMPDIR}/magnav.pdb +bincompare ${TMPDIR}/magnav.pdb ${REFERENCE}/magnav.pdb @@ -207,42 +280,42 @@ bincompare ${TMPDIR}/magnav.pdb reference/magnav.pdb # This test is eerily similar to the NAV Companion test. In fact, the # converted reference file (magnavr.gpu) is identical. rm -f ${TMPDIR}/gpspilot.pdb ${TMPDIR}/gpspilot.gpu ${TMPDIR}/gpspil_t.gpu -${PNAME} -i geo -f geocaching.loc -o gpspilot -F ${TMPDIR}/gpspilot.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpspilot -F ${TMPDIR}/gpspilot.pdb ${PNAME} -i gpspilot -f ${TMPDIR}/gpspilot.pdb -o gpsutil -F ${TMPDIR}/gpspilot.gpu -${PNAME} -i gpspilot -f reference/gpspilot.pdb -o gpsutil -F ${TMPDIR}/gpspil_t.gpu +${PNAME} -i gpspilot -f ${REFERENCE}/gpspilot.pdb -o gpsutil -F ${TMPDIR}/gpspil_t.gpu compare ${TMPDIR}/gpspil_t.gpu ${TMPDIR}/gpspilot.gpu -compare reference/gu.wpt ${TMPDIR}/gpspilot.gpu +compare ${REFERENCE}/gu.wpt ${TMPDIR}/gpspilot.gpu # Cetus GPS for PalmOS # This test is also similar to the NAV Companion test. rm -f ${TMPDIR}/cetus.pdb ${TMPDIR}/cetus.gpu ${TMPDIR}/cetust.gpu -${PNAME} -i geo -f geocaching.loc -o cetus -F ${TMPDIR}/cetus.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o cetus -F ${TMPDIR}/cetus.pdb ${PNAME} -i cetus -f ${TMPDIR}/cetus.pdb -o gpsutil -F ${TMPDIR}/cetus.gpu -${PNAME} -i cetus -f reference/cetus.pdb -o gpsutil -F ${TMPDIR}/cetust.gpu +${PNAME} -i cetus -f ${REFERENCE}/cetus.pdb -o gpsutil -F ${TMPDIR}/cetust.gpu compare ${TMPDIR}/cetust.gpu ${TMPDIR}/cetus.gpu -compare reference/cetus.gpu ${TMPDIR}/cetus.gpu +compare ${REFERENCE}/cetus.gpu ${TMPDIR}/cetus.gpu # QuoVadis GPS for PalmOS # This test is derived from the Cetus test above. rm -f ${TMPDIR}/quovadis.pdb ${TMPDIR}/quovadis.gpu ${TMPDIR}/quovadist.gpu -${PNAME} -i geo -f geocaching.loc -o quovadis -F ${TMPDIR}/quovadis.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o quovadis -F ${TMPDIR}/quovadis.pdb ${PNAME} -i quovadis -f ${TMPDIR}/quovadis.pdb -o gpsutil -F ${TMPDIR}/quovadis.gpu -${PNAME} -i quovadis -f reference/quovadis.pdb -o gpsutil -F ${TMPDIR}/quovadist.gpu +${PNAME} -i quovadis -f ${REFERENCE}/quovadis.pdb -o gpsutil -F ${TMPDIR}/quovadist.gpu compare ${TMPDIR}/quovadist.gpu ${TMPDIR}/quovadis.gpu -compare reference/quovadis.gpu ${TMPDIR}/quovadis.gpu +compare ${REFERENCE}/quovadis.gpu ${TMPDIR}/quovadis.gpu # GpsDrive rm -f ${TMPDIR}/gpsdrive.txt -${PNAME} -i geo -f geocaching.loc -o gpsdrive -F ${TMPDIR}/gpsdrive.txt -compare ${TMPDIR}/gpsdrive.txt reference -${PNAME} -i gpsdrive -f reference/gpsdrive.txt -o gpsdrive -F ${TMPDIR}/gpsdrive2.txt -compare ${TMPDIR}/gpsdrive2.txt reference/gpsdrive.txt +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpsdrive -F ${TMPDIR}/gpsdrive.txt +compare ${TMPDIR}/gpsdrive.txt ${REFERENCE} +${PNAME} -i gpsdrive -f ${REFERENCE}/gpsdrive.txt -o gpsdrive -F ${TMPDIR}/gpsdrive2.txt +compare ${TMPDIR}/gpsdrive2.txt ${REFERENCE}/gpsdrive.txt # XMapHH Street Atlas USA file format rm -f ${TMPDIR}/xmapwpt.wpt ${TMPDIR}/xmapwpt.xmapwpt -${PNAME} -i xmapwpt -f reference/xmapwpt.wpt -o xmapwpt -F ${TMPDIR}/xmapwpt.xmapwpt +${PNAME} -i xmapwpt -f ${REFERENCE}/xmapwpt.wpt -o xmapwpt -F ${TMPDIR}/xmapwpt.xmapwpt ${PNAME} -i xmapwpt -f ${TMPDIR}/xmapwpt.xmapwpt -o xmapwpt -F ${TMPDIR}/xmapwpt.wpt -compare ${TMPDIR}/xmapwpt.wpt reference +compare ${TMPDIR}/xmapwpt.wpt ${REFERENCE} # XCSV # Test that we can parse a style file, and read and write data in the @@ -256,7 +329,7 @@ echo "IFIELD SHORTNAME,,%s" >> ${TMPDIR}/testo.style echo "IFIELD LAT_DIRDECIMAL,,%c%lf" >> ${TMPDIR}/testo.style echo "IFIELD LON_DECIMALDIR,,%lf%c" >> ${TMPDIR}/testo.style rm -f ${TMPDIR}/xcsv.geo ${TMPDIR}/xcsv.xcsv -${PNAME} -i geo -f geocaching.loc -o xcsv,style=${TMPDIR}/testo.style -F ${TMPDIR}/xcsv.geo +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o xcsv,style=${TMPDIR}/testo.style -F ${TMPDIR}/xcsv.geo ${PNAME} -i xcsv,style=${TMPDIR}/testo.style -f ${TMPDIR}/xcsv.geo -o xcsv,style=${TMPDIR}/testo.style -F ${TMPDIR}/xcsv.xcsv compare ${TMPDIR}/xcsv.geo ${TMPDIR}/xcsv.xcsv @@ -268,8 +341,8 @@ compare ${TMPDIR}/xcsv.geo ${TMPDIR}/xcsv.xcsv # GPX output. rm -fr ${TMPDIR}/ms.gpx ${TMPDIR}/ms[12].gpx -${PNAME} -i mapsource -f reference/mapsource.mps -o gpx -F ${TMPDIR}/ms1.gpx -${PNAME} -i mapsource -f reference/mapsource.mps -o mapsource -F ${TMPDIR}/ms.mps +${PNAME} -i mapsource -f ${REFERENCE}/mapsource.mps -o gpx -F ${TMPDIR}/ms1.gpx +${PNAME} -i mapsource -f ${REFERENCE}/mapsource.mps -o mapsource -F ${TMPDIR}/ms.mps ${PNAME} -i mapsource -f ${TMPDIR}/ms.mps -o gpx -F ${TMPDIR}/ms2.gpx compare ${TMPDIR}/ms1.gpx ${TMPDIR}/ms2.gpx @@ -277,29 +350,29 @@ compare ${TMPDIR}/ms1.gpx ${TMPDIR}/ms2.gpx # MRCB mapsource track test # rm -f ${TMPDIR}/mps-track.mps -${PNAME} -t -i mapsource -f reference/track/mps-track.mps -o mapsource,mpsverout=3 \ +${PNAME} -t -i mapsource -f ${REFERENCE}/track/mps-track.mps -o mapsource,mpsverout=3 \ -F ${TMPDIR}/mps-track.mps -compare ${TMPDIR}/mps-track.mps reference/track/ +compare ${TMPDIR}/mps-track.mps ${REFERENCE}/track/ # Now do a test of reading waypoints from a track-only file - should have an empty result rm -f ${TMPDIR}/mps-track.mps -${PNAME} -i mapsource -f reference/track/mps-track.mps -o mapsource,mpsverout=3 \ +${PNAME} -i mapsource -f ${REFERENCE}/track/mps-track.mps -o mapsource,mpsverout=3 \ -F ${TMPDIR}/mps-track.mps -compare ${TMPDIR}/mps-track.mps reference/mps-empty.mps +compare ${TMPDIR}/mps-track.mps ${REFERENCE}/mps-empty.mps # # MRCB mapsource route test # rm -f ${TMPDIR}/mps-route.mps -${PNAME} -r -i mapsource -f reference/route/route.mps -o mapsource,mpsverout=4 \ +${PNAME} -r -i mapsource -f ${REFERENCE}/route/route.mps -o mapsource,mpsverout=4 \ -F ${TMPDIR}/mps-route.mps -compare ${TMPDIR}/mps-route.mps reference/route/route.mps +compare ${TMPDIR}/mps-route.mps ${REFERENCE}/route/route.mps # Now do a test of reading tracks from a route-only file - should have an empty result rm -f ${TMPDIR}/mps-route.mps -${PNAME} -t -i mapsource -f reference/route/route.mps -o mapsource,mpsverout=3 \ +${PNAME} -t -i mapsource -f ${REFERENCE}/route/route.mps -o mapsource,mpsverout=3 \ -F ${TMPDIR}/mps-route.mps -compare ${TMPDIR}/mps-route.mps reference/mps-empty.mps +compare ${TMPDIR}/mps-route.mps ${REFERENCE}/mps-empty.mps # # Geocaching Database is a binary Palm format that, like the GPX variants @@ -308,7 +381,7 @@ compare ${TMPDIR}/mps-route.mps reference/mps-empty.mps # that one to GPX. # -${PNAME} -i gcdb -f reference/GeocachingDB.PDB -o gpx -F ${TMPDIR}/gcdb1.gpx \ +${PNAME} -i gcdb -f ${REFERENCE}/GeocachingDB.PDB -o gpx -F ${TMPDIR}/gcdb1.gpx \ -o gcdb -F ${TMPDIR}/gcdb1.pdb ${PNAME} -i gpx -f ${TMPDIR}/gcdb1.gpx -o gpx -F ${TMPDIR}/gcdb2.gpx compare ${TMPDIR}/gcdb1.gpx ${TMPDIR}/gcdb1.gpx @@ -318,8 +391,8 @@ compare ${TMPDIR}/gcdb1.gpx ${TMPDIR}/gcdb1.gpx # as an intermediate format for testing the filter. # rm -f ${TMPDIR}/filterdupe.csv1 ${TMPDIR}/filterdupe.csv2 -${PNAME} -i geo -f geocaching.loc -o csv -F ${TMPDIR}/filterdupe.csv1 -${PNAME} -i geo -f geocaching.loc -f geocaching.loc -x duplicate,shortname \ +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o csv -F ${TMPDIR}/filterdupe.csv1 +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -f ${REFERENCE}/../geocaching.loc -x duplicate,shortname \ -o csv -F ${TMPDIR}/filterdupe.csv2 sort_and_compare ${TMPDIR}/filterdupe.csv1 ${TMPDIR}/filterdupe.csv2 @@ -328,8 +401,8 @@ sort_and_compare ${TMPDIR}/filterdupe.csv1 ${TMPDIR}/filterdupe.csv2 # position filter, we can test very similarly to the duplicate filter. # rm -f ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2 -${PNAME} -i geo -f geocaching.loc -o csv -F ${TMPDIR}/filterpos.csv1 -${PNAME} -i geo -f geocaching.loc -f geocaching.loc -x position,distance=5f \ +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o csv -F ${TMPDIR}/filterpos.csv1 +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -f ${REFERENCE}/../geocaching.loc -x position,distance=5f \ -o csv -F ${TMPDIR}/filterpos.csv2 sort_and_compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2 @@ -337,38 +410,39 @@ sort_and_compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2 # Radius filter # rm -f ${TMPDIR}/radius.csv -${PNAME} -i geo -f geocaching.loc \ +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc \ -x radius,lat=35.9720,lon=-87.1347,distance=14.7 \ -o csv -F ${TMPDIR}/radius.csv -compare ${TMPDIR}/radius.csv reference/ +compare ${TMPDIR}/radius.csv ${REFERENCE}/ # # magellan SD card waypoint / route format # rm -f ${TMPDIR}/magellan.rte -${PNAME} -r -i magellan -f reference/route/magellan.rte -o magellan \ +${PNAME} -r -i magellan -f ${REFERENCE}/route/magellan.rte -o magellan \ -F ${TMPDIR}/magellan.rte -compare ${TMPDIR}/magellan.rte reference/route/magellan.rte +compare ${TMPDIR}/magellan.rte ${REFERENCE}/route/magellan.rte + # # GPX routes -- since GPX contains a date stamp, tests will always # fail, so we use magellan as an interim format... # rm -f ${TMPDIR}/gpxroute.gpx ${TMPDIR}/maggpx.rte -${PNAME} -r -i gpx -f reference/route/route.gpx -o gpx \ +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx -o gpx \ -F ${TMPDIR}/gpxroute.gpx ${PNAME} -r -i gpx -f ${TMPDIR}/gpxroute.gpx -o magellan \ -F ${TMPDIR}/maggpx.rte -compare ${TMPDIR}/maggpx.rte reference/route/magellan.rte +compare ${TMPDIR}/maggpx.rte ${REFERENCE}/route/magellan.rte # # GPX tracks -- since GPX contains a date stamp, tests will always # fail, so we use magellan as an interim format... # rm -f ${TMPDIR}/gpxtrack.gpx ${TMPDIR}/maggpx.trk -${PNAME} -t -i gpx -f reference/track/tracks.gpx -o gpx \ +${PNAME} -t -i gpx -f ${REFERENCE}/track/tracks.gpx -o gpx \ -F ${TMPDIR}/gpxtrack.gpx -${PNAME} -t -i magellan -f reference/track/meridian.trk -o gpx \ +${PNAME} -t -i magellan -f ${REFERENCE}/track/meridian.trk -o gpx \ -F ${TMPDIR}/maggpx.trk compare ${TMPDIR}/maggpx.trk ${TMPDIR}/gpxtrack.gpx @@ -376,24 +450,24 @@ compare ${TMPDIR}/maggpx.trk ${TMPDIR}/gpxtrack.gpx # MAPSEND waypoint / route format # rm -f ${TMPDIR}/route.mapsend -${PNAME} -r -i mapsend -f reference/route/route.mapsend -o mapsend \ +${PNAME} -r -i mapsend -f ${REFERENCE}/route/route.mapsend -o mapsend \ -F ${TMPDIR}/route.mapsend -compare ${TMPDIR}/route.mapsend reference/route/ +bincompare ${TMPDIR}/route.mapsend ${REFERENCE}/route/route.mapsend # # MAPSEND track format # rm -f ${TMPDIR}/mapsend.trk -${PNAME} -t -i mapsend -f reference/track/mapsend.trk -o mapsend \ +${PNAME} -t -i mapsend -f ${REFERENCE}/track/mapsend.trk -o mapsend,trkver=3 \ -F ${TMPDIR}/mapsend.trk -compare ${TMPDIR}/mapsend.trk reference/track/ +compare ${TMPDIR}/mapsend.trk ${REFERENCE}/track/ # # copilot # rm -f ${TMPDIR}/copilot.pdb -${PNAME} -i copilot -f reference/UKultralight.pdb -o copilot -F ${TMPDIR}/cop.pdb -${PNAME} -i copilot -f reference/UKultralight.pdb -o gpx -F ${TMPDIR}/cop1.gpx +${PNAME} -i copilot -f ${REFERENCE}/UKultralight.pdb -o copilot -F ${TMPDIR}/cop.pdb +${PNAME} -i copilot -f ${REFERENCE}/UKultralight.pdb -o gpx -F ${TMPDIR}/cop1.gpx ${PNAME} -i copilot -f ${TMPDIR}/cop.pdb -o gpx -F ${TMPDIR}/cop2.gpx compare ${TMPDIR}/cop1.gpx ${TMPDIR}/cop2.gpx @@ -401,8 +475,8 @@ compare ${TMPDIR}/cop1.gpx ${TMPDIR}/cop2.gpx # EasyGPS. Another binary format. # rm -f ${TMPDIR}/easy.loc -${PNAME} -i easygps -f reference/easygps.loc -o easygps -F ${TMPDIR}/ez.loc -${PNAME} -i easygps -f reference/easygps.loc -o gpx -F ${TMPDIR}/ez1.gpx +${PNAME} -i easygps -f ${REFERENCE}/easygps.loc -o easygps -F ${TMPDIR}/ez.loc +${PNAME} -i easygps -f ${REFERENCE}/easygps.loc -o gpx -F ${TMPDIR}/ez1.gpx ${PNAME} -i easygps -f ${TMPDIR}/ez.loc -o gpx -F ${TMPDIR}/ez2.gpx compare ${TMPDIR}/ez1.gpx ${TMPDIR}/ez2.gpx @@ -410,107 +484,107 @@ compare ${TMPDIR}/ez1.gpx ${TMPDIR}/ez2.gpx # GPilotS. A Palm format. Another binary format that # # rm -f ${TMPDIR/gpilots.l -#${PNAME} -i easygps -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx -${PNAME} -i geo -f geocaching.loc -o gpilots -F ${TMPDIR}/blah.pdb +#${PNAME} -i easygps -f ${REFERENCE}/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o gpilots -F ${TMPDIR}/blah.pdb ${PNAME} -i gpilots -f ${TMPDIR}/blah.pdb -o gpx -F ${TMPDIR}/1.gpx -${PNAME} -i gpilots -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/2.gpx +${PNAME} -i gpilots -f ${REFERENCE}/gpilots.pdb -o gpx -F ${TMPDIR}/2.gpx compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx -#${PNAME} -i easygps -f reference/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx +#${PNAME} -i easygps -f ${REFERENCE}/gpilots.pdb -o gpx -F ${TMPDIR}/gp.gpx # # Navicache. -${PNAME} -i navicache -f reference/navicache.xml -o gpsutil -F ${TMPDIR}/navi.wpt -compare ${TMPDIR}/navi.wpt reference/navicache.ref +${PNAME} -i navicache -f ${REFERENCE}/navicache.xml -o gpsutil -F ${TMPDIR}/navi.wpt +compare ${TMPDIR}/navi.wpt ${REFERENCE}/navicache.ref # # # CoastalExplorer.. -${PNAME} -r -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx -compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref +${PNAME} -r -i coastexp -f ${REFERENCE}/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx +compare ${TMPDIR}/coastexp.gpx ${REFERENCE}/coastexp.ref ${PNAME} -r -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob -compare ${TMPDIR}/coastexp.nob reference/coastexp.ref2 -${PNAME} -w -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx -compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref3 +compare ${TMPDIR}/coastexp.nob ${REFERENCE}/coastexp.ref2 +${PNAME} -w -i coastexp -f ${REFERENCE}/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx +compare ${TMPDIR}/coastexp.gpx ${REFERENCE}/coastexp.ref3 ${PNAME} -w -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob -compare ${TMPDIR}/coastexp.nob reference/coastexp.ref4 +compare ${TMPDIR}/coastexp.nob ${REFERENCE}/coastexp.ref4 # # PsiTrex. A text format that can't be handled by XCSV due to context of # data based on other data values in the file # Waypoints first rm -f ${TMPDIR}/psit-ww.txt ${TMPDIR}/psit-ww.mps -${PNAME} -i psitrex -f reference/psitwpts.txt -o mapsource -F ${TMPDIR}/psit-ww.mps +${PNAME} -i psitrex -f ${REFERENCE}/psitwpts.txt -o mapsource -F ${TMPDIR}/psit-ww.mps ${PNAME} -i mapsource -f ${TMPDIR}/psit-ww.mps -o psitrex -F ${TMPDIR}/psit-ww.txt -compare reference/psitwpts.txt ${TMPDIR}/psit-ww.txt +compare ${REFERENCE}/psitwpts.txt ${TMPDIR}/psit-ww.txt # Now test correct "empty" handling - ask for routes when there aren't any # Uses mapsource as the empty handling for this has already happened above rm -f ${TMPDIR}/psit-wr.mps -${PNAME} -r -i psitrex -f reference/psitwpts.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-wr.mps -compare reference/mps-empty.mps ${TMPDIR}/psit-wr.mps +${PNAME} -r -i psitrex -f ${REFERENCE}/psitwpts.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-wr.mps +compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-wr.mps # Routes next rm -f ${TMPDIR}/psit-rr.txt ${TMPDIR}/psit-rr.mps -${PNAME} -r -i psitrex -f reference/route/psitrtes.txt -o mapsource -F ${TMPDIR}/psit-rr.mps +${PNAME} -r -i psitrex -f ${REFERENCE}/route/psitrtes.txt -o mapsource -F ${TMPDIR}/psit-rr.mps ${PNAME} -r -i mapsource -f ${TMPDIR}/psit-rr.mps -o psitrex -F ${TMPDIR}/psit-rr.txt -compare reference/route/psitrtes.txt ${TMPDIR}/psit-rr.txt +compare ${REFERENCE}/route/psitrtes.txt ${TMPDIR}/psit-rr.txt # Now test correct "empty" handling - ask for tracks when there aren't any # Uses mapsource as the empty handling for this has already happened above rm -f ${TMPDIR}/psit-rt.mps -${PNAME} -t -i psitrex -f reference/route/psitrtes.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-rt.mps -compare reference/mps-empty.mps ${TMPDIR}/psit-rt.mps +${PNAME} -t -i psitrex -f ${REFERENCE}/route/psitrtes.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-rt.mps +compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-rt.mps # Tracks last rm -f ${TMPDIR}/psit-tt.txt ${TMPDIR}/psit-tt.mps -${PNAME} -t -i psitrex -f reference/track/psittrks.txt -o mapsource -F ${TMPDIR}/psit-tt.mps +${PNAME} -t -i psitrex -f ${REFERENCE}/track/psittrks.txt -o mapsource -F ${TMPDIR}/psit-tt.mps ${PNAME} -t -i mapsource -f ${TMPDIR}/psit-tt.mps -o psitrex -F ${TMPDIR}/psit-tt.txt -compare reference/track/psittrks.txt ${TMPDIR}/psit-tt.txt +compare ${REFERENCE}/track/psittrks.txt ${TMPDIR}/psit-tt.txt # Now test correct "empty" handling - ask for waypoints when there aren't any # Uses mapsource as the empty handling for this has already happened above rm -f ${TMPDIR}/psit-tw.mps -${PNAME} -i psitrex -f reference/track/psittrks.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-tw.mps -compare reference/mps-empty.mps ${TMPDIR}/psit-tw.mps +${PNAME} -i psitrex -f ${REFERENCE}/track/psittrks.txt -o mapsource,mpsverout=3 -F ${TMPDIR}/psit-tw.mps +compare ${REFERENCE}/mps-empty.mps ${TMPDIR}/psit-tw.mps # # Arc Distance filter # rm -f ${TMPDIR}/arcdist.txt -${PNAME} -i xmap -f reference/arcdist_input.txt \ - -x arc,file=reference/arcdist_arc.txt,distance=1 \ +${PNAME} -i xmap -f ${REFERENCE}/arcdist_input.txt \ + -x arc,file=${REFERENCE}/arcdist_arc.txt,distance=1 \ -o xmap -F ${TMPDIR}/arcdist.txt -compare ${TMPDIR}/arcdist.txt reference/arcdist_output.txt +compare ${TMPDIR}/arcdist.txt ${REFERENCE}/arcdist_output.txt # # Polygon filter # rm -f ${TMPDIR}/polygon.txt -${PNAME} -i xmap -f reference/arcdist_input.txt \ - -x polygon,file=reference/polygon_allencty.txt \ +${PNAME} -i xmap -f ${REFERENCE}/arcdist_input.txt \ + -x polygon,file=${REFERENCE}/polygon_allencty.txt \ -o xmap -F ${TMPDIR}/polygon.txt -compare ${TMPDIR}/polygon.txt reference/polygon_output.txt +compare ${TMPDIR}/polygon.txt ${REFERENCE}/polygon_output.txt # # Simplify filter # rm -f ${TMPDIR}/simplify.txt -${PNAME} -r -i gpx -f reference/route/route.gpx \ +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ -x simplify,count=10 \ -o arc -F ${TMPDIR}/simplify.txt -compare ${TMPDIR}/simplify.txt reference/simplify_output.txt +compare ${TMPDIR}/simplify.txt ${REFERENCE}/simplify_output.txt # # Route reversal filter. Do it twice and be sure we get what we # started with. # rm -f ${TMPDIR}/reverse1.arc ${TMPDIR}/reverse2.arc ${TMPDIR}/reference.arc -${PNAME} -r -i gpx -f reference/route/route.gpx \ +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ -o arc -F ${TMPDIR}/reference.arc -${PNAME} -r -i gpx -f reference/route/route.gpx \ +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ -x reverse \ -o arc -F ${TMPDIR}/reverse1.arc -${PNAME} -r -i gpx -f reference/route/route.gpx \ +${PNAME} -r -i gpx -f ${REFERENCE}/route/route.gpx \ -x reverse \ -x reverse \ -o arc -F ${TMPDIR}/reverse2.arc @@ -531,25 +605,28 @@ compare ${TMPDIR}/reference.arc ${TMPDIR}/reverse2.arc # test it against itself. # rm -f ${TMPDIR}/gn.pdb ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx -${PNAME} -i geoniche -f reference/geoniche.pdb -o geoniche -F ${TMPDIR}/gn.pdb -${PNAME} -i geoniche -f reference/geoniche.pdb -o gpx -F ${TMPDIR}/1.gpx +${PNAME} -i geoniche -f ${REFERENCE}/geoniche.pdb -o geoniche -F ${TMPDIR}/gn.pdb +${PNAME} -i geoniche -f ${REFERENCE}/geoniche.pdb -o gpx -F ${TMPDIR}/1.gpx ${PNAME} -i geoniche -f ${TMPDIR}/gn.pdb -o gpx -F ${TMPDIR}/2.gpx compare ${TMPDIR}/1.gpx ${TMPDIR}/2.gpx +# +${PNAME} -i geoniche -f ${REFERENCE}/gn-targets.pdb -o gpx -F ${TMPDIR}/gn-targets.gpx +compare ${TMPDIR}/gn-targets.gpx ${REFERENCE}/gn-targets.gpx # # saroute covers *.anr, *.rte, and *.rtd, but I only have an .anr for testing. # Unfortunately for us, this is a read-only format for now. # -${PNAME} -t -i saroute -f reference/track/i65.anr -o gpx -F ${TMPDIR}/gpl1.gpx -${PNAME} -t -i gpx -f reference/track/i65.anr.gpx -o gpx -F ${TMPDIR}/gpl2.gpx +${PNAME} -t -i saroute -f ${REFERENCE}/track/i65.anr -o gpx -F ${TMPDIR}/gpl1.gpx +${PNAME} -t -i gpx -f ${REFERENCE}/track/i65.anr.gpx -o gpx -F ${TMPDIR}/gpl2.gpx compare ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx # # Delorme GPL file. This is sort of a track format. # rm -f ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx ${TMPDIR}/gpl1.gpl -${PNAME} -t -i gpl -f reference/track/webpark1.gpl -o gpx -F ${TMPDIR}/gpl1.gpx -${PNAME} -t -i gpl -f reference/track/webpark1.gpl -o gpl -F ${TMPDIR}/gpl1.gpl +${PNAME} -t -i gpl -f ${REFERENCE}/track/webpark1.gpl -o gpx -F ${TMPDIR}/gpl1.gpx +${PNAME} -t -i gpl -f ${REFERENCE}/track/webpark1.gpl -o gpl -F ${TMPDIR}/gpl1.gpl ${PNAME} -t -i gpl -f ${TMPDIR}/gpl1.gpl -o gpx -F ${TMPDIR}/gpl2.gpx compare ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx @@ -557,113 +634,117 @@ compare ${TMPDIR}/gpl1.gpx ${TMPDIR}/gpl2.gpx # NetStumbler Summary File (read-only) # rm -f ${TMPDIR}/netstumbler.mps -${PNAME} -i netstumbler -f reference/netstumbler.txt -o mapsource -F ${TMPDIR}/netstumbler.mps -bincompare ${TMPDIR}/netstumbler.mps reference/netstumbler.mps +${PNAME} -i netstumbler -f ${REFERENCE}/netstumbler.txt -o mapsource -F ${TMPDIR}/netstumbler.mps +bincompare ${TMPDIR}/netstumbler.mps ${REFERENCE}/netstumbler.mps # # IGC tests # rm -f ${TMPDIR}/igc*out -${PNAME} -i gpx -f reference/igc1.gpx -o igc -F ${TMPDIR}/igc.out +${PNAME} -i gpx -f ${REFERENCE}/igc1.gpx -o igc -F ${TMPDIR}/igc.out sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out -compare ${TMPDIR}/igc_sed.out reference/igc1_igc.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc1_igc.out ${PNAME} -i igc -f ${TMPDIR}/igc.out -o gpx -F ${TMPDIR}/igc.gpx -compare ${TMPDIR}/igc.gpx reference/igc1_gpx.out +compare ${TMPDIR}/igc.gpx ${REFERENCE}/igc1_gpx.out ${PNAME} -i gpx -f ${TMPDIR}/igc.gpx -o igc -F ${TMPDIR}/igc.out sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out -compare ${TMPDIR}/igc_sed.out reference/igc1_igc.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc1_igc.out -${PNAME} -i gpx -f reference/igc1_baro.gpx -i igc -f reference/igc1_igc.out -o igc,timeadj=auto -F ${TMPDIR}/igc.out +${PNAME} -i gpx -f ${REFERENCE}/igc1_baro.gpx -i igc -f ${REFERENCE}/igc1_igc.out -o igc,timeadj=auto -F ${TMPDIR}/igc.out sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out -compare ${TMPDIR}/igc_sed.out reference/igc1_3d.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc1_3d.out -${PNAME} -i igc -f reference/igc2.igc -o gpx -F ${TMPDIR}/igc.gpx -compare ${TMPDIR}/igc.gpx reference/igc2_gpx.out +${PNAME} -i igc -f ${REFERENCE}/igc2.igc -o gpx -F ${TMPDIR}/igc.gpx +compare ${TMPDIR}/igc.gpx ${REFERENCE}/igc2_gpx.out ${PNAME} -i gpx -f ${TMPDIR}/igc.gpx -o igc -F ${TMPDIR}/igc.out sed '/^LXXXGenerated by GPSBabel Version/d' ${TMPDIR}/igc.out > ${TMPDIR}/igc_sed.out -compare ${TMPDIR}/igc_sed.out reference/igc2_igc.out +compare ${TMPDIR}/igc_sed.out ${REFERENCE}/igc2_igc.out ${PNAME} -i igc -f ${TMPDIR}/igc.out -o gpx -F ${TMPDIR}/igc.gpx -compare ${TMPDIR}/igc.gpx reference/igc2_gpx.out +compare ${TMPDIR}/igc.gpx ${REFERENCE}/igc2_gpx.out # # Google Maps XML test # rm -f ${TMPDIR}/google.out -${PNAME} -i google -f reference/google.xml -o arc -F ${TMPDIR}/google.out -compare ${TMPDIR}/google.out reference/google.arc +${PNAME} -i google -f ${REFERENCE}/google.xml -o csv -F ${TMPDIR}/google.out +compare ${TMPDIR}/google.out ${REFERENCE}/google.csv + +rm -f ${TMPDIR}/google.out +${PNAME} -i google -f ${REFERENCE}/google.js -o csv -F ${TMPDIR}/google.out +compare ${TMPDIR}/google.out ${REFERENCE}/google.csv rm -f ${TMPDIR}/google.out -${PNAME} -i google -f reference/google.js -o arc -F ${TMPDIR}/google.out -compare ${TMPDIR}/google.out reference/google.arc +${PNAME} -i google -f ${REFERENCE}/google_jan_06.html -o csv -F ${TMPDIR}/google.out +compare ${TMPDIR}/google.out ${REFERENCE}/google_jan_06.csv # # DeLorme .an1 tests # rm -f ${TMPDIR}/an1.out -${PNAME} -i an1 -f reference/foo.an1 -o csv -F ${TMPDIR}/an1.out -compare ${TMPDIR}/an1.out reference/an1-in.ref +${PNAME} -i an1 -f ${REFERENCE}/foo.an1 -o csv -F ${TMPDIR}/an1.out +compare ${TMPDIR}/an1.out ${REFERENCE}/an1-in.ref rm -f ${TMPDIR}/an1.out -${PNAME} -i an1 -f reference/foo.an1 -o an1 -F ${TMPDIR}/an1.out -compare ${TMPDIR}/an1.out reference/an1-an1.ref +${PNAME} -i an1 -f ${REFERENCE}/foo.an1 -o an1 -F ${TMPDIR}/an1.out +bincompare ${TMPDIR}/an1.out ${REFERENCE}/an1-an1.ref rm -f ${TMPDIR}/an1.out -${PNAME} -i xmap -f reference/xmap -o an1 -F ${TMPDIR}/an1.out -compare ${TMPDIR}/an1.out reference/an1-out.ref +${PNAME} -i xmap -f ${REFERENCE}/xmap -o an1 -F ${TMPDIR}/an1.out +bincompare ${TMPDIR}/an1.out ${REFERENCE}/an1-out.ref rm -f ${TMPDIR}/an1.out -${PNAME} -i google -f reference/google.js -o an1 -F ${TMPDIR}/an1.out -compare ${TMPDIR}/an1.out reference/an1-line-out.ref +${PNAME} -i google -f ${REFERENCE}/google.js -o an1 -F ${TMPDIR}/an1.out +bincompare ${TMPDIR}/an1.out ${REFERENCE}/an1-line-out.ref # # TomTom .ov2 tests # rm -f ${TMPDIR}/ov2.out -${PNAME} -i arc -f reference/google.arc -o tomtom -F ${TMPDIR}/ov2.out -compare ${TMPDIR}/ov2.out reference/ov2-arc-out.ref +${PNAME} -i arc -f ${REFERENCE}/google.arc -o tomtom -F ${TMPDIR}/ov2.out +compare ${TMPDIR}/ov2.out ${REFERENCE}/ov2-arc-out.ref rm -f ${TMPDIR}/ov2.out -${PNAME} -i geo -f reference/gl.loc -o tomtom -F ${TMPDIR}/ov2.out -compare ${TMPDIR}/ov2.out reference/ov2-geo-out.ref +${PNAME} -i geo -f ${REFERENCE}/gl.loc -o tomtom -F ${TMPDIR}/ov2.out +compare ${TMPDIR}/ov2.out ${REFERENCE}/ov2-geo-out.ref rm -f ${TMPDIR}/ov2.out -${PNAME} -i tomtom -f reference/ov2-geo-out.ref -o gpsutil -F ${TMPDIR}/ov2.out -compare ${TMPDIR}/ov2.out reference/ov2-in.ref +${PNAME} -i tomtom -f ${REFERENCE}/ov2-geo-out.ref -o gpsutil -F ${TMPDIR}/ov2.out +compare ${TMPDIR}/ov2.out ${REFERENCE}/ov2-in.ref # # XCSV "human readable" tests # rm -f ${TMPDIR}/humanread.out -${PNAME} -i xcsv,style=reference/humanread.style -f reference/human.in -o arc -F ${TMPDIR}/humanread.out -compare ${TMPDIR}/humanread.out reference/humanread.out +${PNAME} -i xcsv,style=${REFERENCE}/humanread.style -f ${REFERENCE}/human.in -o arc -F ${TMPDIR}/humanread.out +compare ${TMPDIR}/humanread.out ${REFERENCE}/humanread.out rm -f ${TMPDIR}/humanwrite.out -${PNAME} -i xcsv,style=reference/humanread.style -f reference/human.in -o xcsv,style=reference/humanwrite.style -F ${TMPDIR}/humanwrite.out -compare ${TMPDIR}/humanwrite.out reference/humanwrite.out +${PNAME} -i xcsv,style=${REFERENCE}/humanread.style -f ${REFERENCE}/human.in -o xcsv,style=${REFERENCE}/humanwrite.style -F ${TMPDIR}/humanwrite.out +compare ${TMPDIR}/humanwrite.out ${REFERENCE}/humanwrite.out # # XCSV "path distance" test # rm -f ${TMPDIR}/pathdist.out -${PNAME} -i magellan -f reference/dusky.trk -o xcsv,style=reference/gnuplot.style -F ${TMPDIR}/pathdist.out -compare ${TMPDIR}/pathdist.out reference/dusky.gnuplot +${PNAME} -i magellan -f ${REFERENCE}/dusky.trk -o xcsv,style=${REFERENCE}/gnuplot.style -F ${TMPDIR}/pathdist.out +compare ${TMPDIR}/pathdist.out ${REFERENCE}/dusky.gnuplot # hsandv rm -f ${TMPDIR}/hsandv.exp ${TMPDIR}/1.exp ${TMPDIR}/1.exp ${TMPDIR}/Glad_5.exp -${PNAME} -i geo -f geocaching.loc -o hsandv -F ${TMPDIR}/hsandv.exp -compare ${TMPDIR}/hsandv.exp reference +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o hsandv -F ${TMPDIR}/hsandv.exp +compare ${TMPDIR}/hsandv.exp ${REFERENCE} #the hsandv format is too lossy to do this test :( #${PNAME} -i hsandv -f ${TMPDIR}/hsandv.exp -o geo -F ${TMPDIR}/1.exp -#${PNAME} -i hsandv -f reference/hsandv.exp -o geo -F ${TMPDIR}/2.exp +#${PNAME} -i hsandv -f ${REFERENCE}/hsandv.exp -o geo -F ${TMPDIR}/2.exp #compare ${TMPDIR}/1.exp ${TMPDIR}/2.exp #test conversion from v4 to v5 files -${PNAME} -i hsandv -f reference/Glad_4.exp -o hsandv -F ${TMPDIR}/Glad_5.exp +${PNAME} -i hsandv -f ${REFERENCE}/Glad_4.exp -o hsandv -F ${TMPDIR}/Glad_5.exp # FIXME: Can't compare directly because of potential FP rounding. # FIXME: compare ${TMPDIR}/Glad_5.exp reference @@ -673,68 +754,71 @@ ${PNAME} -i hsandv -f reference/Glad_4.exp -o hsandv -F ${TMPDIR}/Glad_5.exp # exercise all of the currently-extant filter code. # -${PNAME} -i geo -f geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o arc -F ${TMPDIR}/stackfilt.txt +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -x stack,push,copy,nowarn -x stack,push,copy -x stack,push -x stack,pop,replace -x stack,pop,append -x stack,push,copy -x stack,pop,discard -x stack,swap,depth=1 -o arc -F ${TMPDIR}/stackfilt.txt # # 'tabsep' isn't really tested in any non-trivial way, but we do exercise # it. # -${PNAME} -i geo -f geocaching.loc -o tabsep -F - | ${PNAME} -i tabsep -f - -o geo -F ${TMPDIR}/tabsep.out -${PNAME} -i geo -f geocaching.loc -o geo -F ${TMPDIR}/geotabsep.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o tabsep -F ${TMPDIR}/tabsep.in +${PNAME} -i tabsep -f ${TMPDIR}/tabsep.in -o geo -F ${TMPDIR}/tabsep.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/geotabsep.out +compare ${TMPDIR}/tabsep.out ${TMPDIR}/geotabsep.out # # Now do the same for custom - it has the same issues. # -compare ${TMPDIR}/tabsep.out ${TMPDIR}/geotabsep.out -${PNAME} -i geo -f geocaching.loc -o custom -F - | ${PNAME} -i custom -f - -o geo -F ${TMPDIR}/custom.out -${PNAME} -i geo -f geocaching.loc -o geo -F ${TMPDIR}/geocustom.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o custom -F ${TMPDIR}/custom.in +${PNAME} -i custom -f ${TMPDIR}/custom.in -o geo -F ${TMPDIR}/custom.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o geo -F ${TMPDIR}/geocustom.out # # Write something to the various output-only formats # -${PNAME} -i geo -f geocaching.loc -o text -F ${TMPDIR}/text.out -o html -F ${TMPDIR}/html.out -o vcard -F ${TMPDIR}/vcard.out #-o palmdoc -F ${TMPDIR}/pd.out +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o text -F ${TMPDIR}/text.out -o html -F ${TMPDIR}/html.out -o vcard -F ${TMPDIR}/vcard.out #-o palmdoc -F ${TMPDIR}/pd.out # # tef "TourExchangeFormat" read test # rm -f ${TMPDIR}/tef_xml* -${PNAME} -r -i tef -f reference/route/tef_xml.sample.xml -o gpx -F ${TMPDIR}/tef_xml.sample.gpx -compare reference/route/tef_xml.sample.gpx ${TMPDIR}/tef_xml.sample.gpx +${PNAME} -r -i tef -f ${REFERENCE}/route/tef_xml.sample.xml -o gpx -F ${TMPDIR}/tef_xml.sample.gpx +compare ${TMPDIR}/tef_xml.sample.gpx ${REFERENCE}/route/tef_xml.sample.gpx # # PathAway Palm Database .pdb tests # rm -f ${TMPDIR}/pathaway* -${PNAME} -i geo -f geocaching.loc -o pathaway,dbname="pathaway-geo" -F ${TMPDIR}/pathaway-geo.pdb +${PNAME} -i geo -f ${REFERENCE}/../geocaching.loc -o pathaway,dbname="pathaway-geo" -F ${TMPDIR}/pathaway-geo.pdb ${PNAME} -i pathaway -f ${TMPDIR}/pathaway-geo.pdb -o geo -F ${TMPDIR}/pathaway-geo.loc -compare ${TMPDIR}/pathaway-geo.loc reference/pathaway-geo.loc +compare ${TMPDIR}/pathaway-geo.loc ${REFERENCE}/pathaway-geo.loc rm -f ${TMPDIR}/pathaway* -${PNAME} -t -i pathaway -f reference/track/pathaway.pdb -o gpx -F ${TMPDIR}/pathaway.gpx -compare ${TMPDIR}/pathaway.gpx reference/track/pathaway.gpx +${PNAME} -t -i pathaway -f ${REFERENCE}/track/pathaway.pdb -o gpx -F ${TMPDIR}/pathaway.gpx +compare ${TMPDIR}/pathaway.gpx ${REFERENCE}/track/pathaway.gpx # # Garmin GPS Database .gdb tests # rm -f ${TMPDIR}/gdb-* -${PNAME} -w -r -t -i gdb -f reference/gdb-sample.gdb -o gpx -F ${TMPDIR}/gdb-sample.gpx -compare reference/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx -${PNAME} -w -r -t -i gpx -f reference/gdb-sample.gpx -o gdb,ver=1 -F ${TMPDIR}/gdb-sample.gdb -${PNAME} -w -r -t -i gdb -f ${TMPDIR}/gdb-sample.gdb -o gpx -F ${TMPDIR}/gdb-sample.gpx +${PNAME} -i gdb,via -f ${REFERENCE}/gdb-sample.gdb -o gpx -F ${TMPDIR}/gdb-sample.gpx +compare ${REFERENCE}/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx +${PNAME} -i gpx -f ${REFERENCE}/gdb-sample.gpx -o gdb,ver=1 -F ${TMPDIR}/gdb-sample.gdb +${PNAME} -i gdb -f ${TMPDIR}/gdb-sample.gdb -o gpx -F ${TMPDIR}/gdb-sample.gpx # # Because of Garmin coordinates storage gpx is not good for this test -# compare reference/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx +# compare ${REFERENCE}/gdb-sample.gpx ${TMPDIR}/gdb-sample.gpx # +# compare ${TMPDIR}/gdb-sample.gpx ${REFERENCE}/gdb-sample.gpx # # Vito Navigator II .smt tests # rm -f ${TMPDIR}/vitosmt* -${PNAME} -i vitosmt -f reference/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt.gpx -compare ${TMPDIR}/vitosmt.gpx reference/vitosmt.gpx -${PNAME} -t -i vitosmt -f reference/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt_t.gpx -compare ${TMPDIR}/vitosmt_t.gpx reference/track/vitosmt_t.gpx +${PNAME} -i vitosmt -f ${REFERENCE}/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt.gpx +compare ${TMPDIR}/vitosmt.gpx ${REFERENCE}/vitosmt.gpx +${PNAME} -t -i vitosmt -f ${REFERENCE}/vitosmt.smt -o gpx -F ${TMPDIR}/vitosmt_t.gpx +compare ${TMPDIR}/vitosmt_t.gpx ${REFERENCE}/track/vitosmt_t.gpx # # tracks filter tests @@ -742,21 +826,40 @@ compare ${TMPDIR}/vitosmt_t.gpx reference/track/vitosmt_t.gpx rm -f ${TMPDIR}/trackfilter* -${PNAME} -t -i gpx -f reference/track/trackfilter.gpx -x track,pack,split,title="LOG-%Y%m%d" -o gpx -F ${TMPDIR}/trackfilter-new.gpx -grep -v "" sname "" # This is bad... printf "" @@ -11,6 +15,8 @@ function getcap(type, cap, sname, lname) { printf "Yes" } else if (sname == "s_and_t") { printf "[1][2]" + } else if (sname == "an1") { + printf "Yes" } print "" @@ -23,5 +29,6 @@ function getcap(type, cap, sname, lname) { } print "" } + getcap($1, $2, $3, $5) -' > ../babelweb/capabilities.inc > ../babelweb/capabilities.inc +' > @DOCDIR@capabilities.inc > @DOCDIR@capabilities.inc diff --git a/tools/mkchangelog b/tools/mkchangelog new file mode 100644 index 000000000..9d1a27d40 --- /dev/null +++ b/tools/mkchangelog @@ -0,0 +1,62 @@ +#!/bin/sh +# +# creates a RPM compatible ChangeLog file from babelweb/changes.html +# (published at http://www.gpsbabel.org) +# +# !!! input from stdin and output to stdout !!! +# + +LANG='POSIX'; export LANG > /dev/null + +sed -e :a -e 's/<[^<]*>/ /g;//g' -e 's/</\ +BEGIN { line=0; item=0; OUTP="" } +/^20[0-9][0-9]-[0-9][0-9]-/ { # this will be work until 2099 + line++ + item=0 + if (length(OUTP) > 0) + { + printf("%s\n", OUTP) + OUTP="" + } + printf("%s", substr($0, 1, 10)) + next +} +{ if (line==0) next } # skip header stuff +{ + item++; + if (item==1) + { + if (length($0) > 0) OUTP=sprintf(" %s:", $0) + next + } + else if (length($0) > 0) + { + OUTP=sprintf("%s %s", OUTP, $0) + next + } +} +END { if (length(OUTP) > 0) printf("%s\n", OUTP) } +' | +sort -r | # keep sure, lines "YYYY-MM-DD ....." are sorted in descending order +uniq | # and remove duplicates +awk ' +BEGIN { TMx=0 } +{ + DT=sprintf("%s %s %s 00 00 00", substr($0, 1, 4), substr($0, 6, 2), substr($0, 9, 2)) + TM=mktime(DT) + if (TM != TMx) + { + TX=strftime("%a %b %d %Y", TM) + printf("* %s http://www.gpsbabel.org\n", TX) + TMx = TM + } + OUTP=substr($0, 11) + while (substr(OUTP, 1, 1) <= " " ) { OUTP=substr(OUTP, 2) } + printf("- %s \n", OUTP) + next +} +' diff --git a/tools/mkfilelist b/tools/mkfilelist new file mode 100644 index 000000000..09c9df168 --- /dev/null +++ b/tools/mkfilelist @@ -0,0 +1,51 @@ +#!/bin/sh + +# create filelist using CVS Entries files +# +# Parameter 1: base directory where we're looking for the first CVS directory +# Parameter 2: insert directory name "$2" at the beginning of +# resulting filenames +# +# foo> ./tools/mkfilelist . gpsbabel-1.2.8/ +# +# creates a output like the this: +# +# ... +# gpsbabel-1.2.8/win32/gui-2/options.pas +# gpsbabel-1.2.8/win32/gui-2/utils.pas +# gpsbabel-1.2.8/win32/gui-2/GPSBabelGUI.res +# gpsbabel-1.2.8/win32/GPSBabelGUI.exe +# gpsbabel-1.2.8/copilot.c +# gpsbabel-1.2.8/gcdb.c +# gpsbabel-1.2.8/fatal.c +# ... + +function loop() +{ + test -f "$1/CVS/Entries" || return 0 + + case $1 in + /) return 0;; + esac + + IFS="/" + cat "$1/CVS/Entries" | + while read LINE; do + echo "$LINE" | + ( + read LEAD NAME READ + test "x$NAME" == "x" && continue + case $LEAD in + D) + loop "$1/$NAME/" "$2" + ;; + *) + echo "$2$1/$NAME" + ;; + esac + ) + done + IFS=" " +} + +loop "$1" "$2" | sed -e 's|\/\/|\/|g' -e 's|\.\.|\.|g' -e 's|\.\/||g' diff --git a/tools/mkmoreclean b/tools/mkmoreclean new file mode 100644 index 000000000..030e7c13e --- /dev/null +++ b/tools/mkmoreclean @@ -0,0 +1,15 @@ +#!/bin/sh + +# +# delete all files listed in .cvsignore +# + +find . -type d | +while read dirname; do + test -s "$dirname/.cvsignore" || continue + while read filemask; do + test -z "$filemask" && continue + cmd="rm -fv $dirname/$filemask" + ${cmd} + done < "$dirname/.cvsignore" +done diff --git a/tools/mkrpm b/tools/mkrpm new file mode 100644 index 000000000..b83832c93 --- /dev/null +++ b/tools/mkrpm @@ -0,0 +1,93 @@ +#!/bin/sh +# + +SPEC=gpsbabel.spec +TAR_IGNORE="--exclude CVS" +VERSION=$1 +RELEASE=$2 + +if test -x /usr/bin/rpmbuild; then + RPM=rpmbuild +else + RPM=rpm +fi + +DIR=`pwd` +TEMPDIR=/tmp/gpsbabel-rpm.$$ +mkdir -p $TEMPDIR +trap "cd $DIR; rm -fr $TEMPDIR" 0 1 2 3 15 + +function addspec() +{ + echo "$*" >> $SPEC +} + +# create spec file needed for rpm generation +function mkspec() +{ + local REL=`echo $RELEASE | sed 's/^-//'` + test "$REL" == "" && REL=0 + + echo -n "" > $SPEC # create the file + + addspec "Summary: GPSBabel" + addspec "Name: gpsbabel" + addspec "Version: $VERSION" + addspec "Release: $REL" + addspec "License: GPL" + addspec "Group: File tools" + addspec "Source: %{name}-%{version}.tar.bz2" + addspec "BuildRoot: %{_tmppath}/%{name}-%{version}-build" + addspec "URL: http://www.gpsbabel.org" + addspec "" + + addspec "%description" + addspec "Converts GPS waypoint, route and track data from one format type to another." + addspec "" + + addspec "Authors:" + addspec "--------" + + cat $DIR/AUTHORS >> gpsbabel.spec + + addspec "" + addspec "%prep" + addspec "%setup -q" + addspec "" + + addspec "%build" + addspec "./configure" + addspec "make" + addspec "" + addspec "%install" + addspec "rm -rf " + addspec "mkdir -p %{buildroot}/usr/bin " + addspec "install -m 555 gpsbabel %{buildroot}/usr/bin/gpsbabel " + addspec "" + + addspec "%files" + addspec "%defattr(-,root,root)" + addspec "/usr/bin/gpsbabel" + addspec "%doc README* COPYING CHANGELOG AUTHORS readme.xml" + addspec "" + addspec "%changelog" +} + +cd $TEMPDIR + +ln -sf $DIR gpsbabel-$VERSION + +mkspec + +cat $DIR/../babelweb/changes.html | $DIR/tools/mkchangelog > gpsbabel-$VERSION/CHANGELOG +cat gpsbabel-$VERSION/CHANGELOG >> gpsbabel.spec + +cp gpsbabel.spec gpsbabel-$VERSION/ +rm -f gpsbabel.spec + +tar -cj $TAR_IGNORE -f gpsbabel-$VERSION.tar.bz2 gpsbabel-$VERSION/. +rm -f gpsbabel-$VERSION + +${RPM} -ta gpsbabel-$VERSION.tar.bz2 + +cd $DIR diff --git a/tools/mkspec b/tools/mkspec new file mode 100644 index 000000000..6c620bdfa --- /dev/null +++ b/tools/mkspec @@ -0,0 +1,56 @@ +#!/bin/sh +# + +WEB=$1 +VERSION=$2 +RELEASE=$3 # may be empty + +REL=`echo $RELEASE | sed 's/^-//'` +test "$REL" == "" && REL=0 + +cat << EOF +Summary: GPSBabel +Name: gpsbabel +Version: $VERSION +Release: $REL +License: GPL +Group: File tools +Source: %{name}-%{version}.tgz +BuildRoot: %{_tmppath}/%{name}-%{version}-build +URL: http://www.gpsbabel.org + +%description +Converts GPS waypoint, route and track data from one format type to another. + + +Authors: +-------- +EOF + +cat AUTHORS + +cat << EOF + +%prep +%setup -q + + +%build +LDFLAGS="-s" ./configure +make + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/bin +install -m 555 gpsbabel %{buildroot}/usr/bin/gpsbabel + +%files +%defattr(-,root,root) +/usr/bin/gpsbabel +%doc README* COPYING CHANGELOG AUTHORS gpsbabel.html + +%changelog +EOF + +cat $WEB/changes.html | tools/mkchangelog > CHANGELOG +cat CHANGELOG diff --git a/tools/release-process b/tools/release-process new file mode 100644 index 000000000..46bbd9f63 --- /dev/null +++ b/tools/release-process @@ -0,0 +1,10 @@ +0) Ensure 'changes' file is up to date. + Regenerate capabilties. (done by 'make doc') + Refresh public web version. +1) Bump version in configure.in. Commit that. +2) Go to empty directory. Check out tree. +3) 'make release' +4) Visit https://sourceforge.net/project/admin/editpackages.php?group_id=58972 + to make new releases public. +5) Send announcemnts to gpsbabel-announce, gpsbabel-misc, gpsbabel-code, + freshmeat, geocaching forums, various yahoo groups (which?) diff --git a/tpg.c b/tpg.c index b0ecaba80..122fa6488 100644 --- a/tpg.c +++ b/tpg.c @@ -1,6 +1,8 @@ /* - National Geographic Topo! Waypoint + National Geographic Topo! TPG file support (Waypoints/Routes) Contributed to gpsbabel by Alex Mottram + + For Topo! version 2.x. Routes are currently not implemented. Copyright (C) 2002 Alex Mottram, geo_alexm at cox-internet.com @@ -32,10 +34,18 @@ static FILE *tpg_file_in; static FILE *tpg_file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; +static char *tpg_datum_opt; +static int tpg_datum_idx; static unsigned int waypt_out_count; +static +arglist_t tpg_args[] = { + {"datum", &tpg_datum_opt, "Datum (default=NAD27)", "N. America 1927 mean", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + static int tpg_fread(void *buff, size_t size, size_t members, FILE * fp) { @@ -44,7 +54,8 @@ tpg_fread(void *buff, size_t size, size_t members, FILE * fp) br = fread(buff, size, members, fp); if (br != members) { - fatal(MYNAME ": requested to read %d bytes, read %d bytes.\n", members, br); + fatal(MYNAME ": requested to read %lu bytes, read %lu bytes.\n", + (unsigned long) members, (unsigned long) br); } return (br); @@ -54,20 +65,15 @@ static double tpg_fread_double(FILE *fp) { unsigned char buf[8]; - unsigned char sbuf[8]; - tpg_fread(buf, 1, 8, fp); - le_read64(sbuf, buf); - return *(double *)sbuf; + return le_read_double(buf); } static void tpg_fwrite_double(double x, FILE *fp) { - unsigned char *cptr = (unsigned char *)&x; unsigned char cbuf[8]; - - le_read64(cbuf, cptr); + le_write_double(cbuf,x); fwrite(cbuf, 8, 1, fp); } @@ -85,9 +91,19 @@ valid_tpg_header(char * header, int len) return memcmp(header_bytes, header, len); } +static void +tpg_common_init(void) +{ + tpg_datum_idx = GPS_Lookup_Datum_Index(tpg_datum_opt); + if (tpg_datum_idx < 0) { + fatal(MYNAME ": Datum '%s' is not recognized.\n", tpg_datum_opt); + } +} + static void tpg_rd_init(const char *fname) { + tpg_common_init(); tpg_file_in = xfopen(fname, "rb", MYNAME); } @@ -100,6 +116,7 @@ tpg_rd_deinit(void) static void tpg_wr_init(const char *fname) { + tpg_common_init(); tpg_file_out = xfopen(fname, "wb", MYNAME); mkshort_handle = mkshort_new_handle(); waypt_out_count = 0; @@ -108,7 +125,7 @@ tpg_wr_init(const char *fname) static void tpg_wr_deinit(void) { - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); fclose(tpg_file_out); } @@ -142,9 +159,10 @@ tpg_read(void) stringsize = buff[0]; - tpg_fread(&buff[0], stringsize, 1, tpg_file_in); - - buff[stringsize] = '\0'; + if (stringsize) + tpg_fread(&buff[0], stringsize, 1, tpg_file_in); + + buff[stringsize] = '\0'; wpt_tmp->shortname = xstrdup(buff); @@ -162,7 +180,7 @@ tpg_read(void) /* 2 bytes - elevation in feet */ tpg_fread(&buff[0], 2, 1, tpg_file_in); - elev = (le_read16(&buff[0]) * .3048); /* feets to meters */ + elev = FEET_TO_METERS(le_read16(&buff[0])); /* convert incoming NAD27/CONUS coordinates to WGS84 */ GPS_Math_Known_Datum_To_WGS84_M( @@ -172,7 +190,7 @@ tpg_read(void) &wpt_tmp->latitude, &wpt_tmp->longitude, &amt, - 78); + tpg_datum_idx); wpt_tmp->altitude = elev; @@ -255,14 +273,14 @@ tpg_waypt_pr(const waypoint *wpt) &lat, &lon, &amt, - 78); + tpg_datum_idx); /* swap the sign back *after* the datum conversion */ lon *= -1.0; /* convert meters back to feets */ - elev = (short int) (wpt->altitude * 3.2808); + elev = (short int) METERS_TO_FEET(wpt->altitude); /* 1 bytes stringsize for shortname */ c = strlen(shortname); @@ -364,5 +382,7 @@ ff_vecs_t tpg_vecs = { tpg_wr_deinit, tpg_read, tpg_write, - NULL + NULL, + tpg_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/tpo.README.patch b/tpo.README.patch new file mode 100644 index 000000000..048b4c579 --- /dev/null +++ b/tpo.README.patch @@ -0,0 +1,51 @@ +Index: README +=================================================================== +RCS file: /cvsroot/gpsbabel/gpsbabel/README,v +retrieving revision 1.145 +diff -p -u -r1.145 README +--- README 26 Oct 2005 23:54:45 -0000 1.145 ++++ README 31 Oct 2005 22:21:04 -0000 +@@ -467,9 +467,10 @@ THE FORMATS + + TPG + +- National Geographic Topo! Waypoint Format. This filter +- reads and writes .TPG files created by various editions of NG Topo! +- This filter will *not* work with the newer combined .TPO files. ++ National Geographic Topo! Waypoint and Route Format. This ++ format reads and writes .TPG files created by various editions ++ of NG Topo! This filter will *not* work with the newer combined ++ .TPO files. Reading/writing of route data is not supported yet. + + The option 'datum="datum name"' can be used to override the + default of NAD27 ("N. America 1927 mean") which is correct +@@ -478,6 +479,29 @@ THE FORMATS + + Contributed by Alex Mottram. + ++ TPO ++ ++ National Geographic Topo! Track Format. This format reads ++ and writes .TPO files created by various editions of NG Topo! ++ version 2.7.7 or earlier. This format will *not* work with the ++ newer .TPO files (version 3.0 and later) that have TPG data ++ combined into them. ++ ++ When writing TPO files, note that every TOPO! state edition ++ employs a slightly different data format, so you will need to ++ specify which state edition to generate output for. The current ++ supported states are CA, NY, NJ, MA, CT, RI, NH, VT, ME. It's ++ fairly easy to add support for additional states. Instructions ++ are in the source code. ++ ++ Additional options: ++ dumpheader - (0/1) Display the file header bytes (useful when ++ adding support for a new state) ++ state - State map format to write, default=CA ++ ++ Contributed by Steve Chamberlin. ++ ++ + HOLUX + + The Holuxgm-100 (e-fox) gps receiver uses standard compact diff --git a/tpo.c b/tpo.c new file mode 100644 index 000000000..505d821d1 --- /dev/null +++ b/tpo.c @@ -0,0 +1,1962 @@ +/* + National Geographic Topo! TPO file support. + 2.x support contributed to gpsbabel by Steve Chamberlin. + 3.x support contributed to gpsbabel by Curt Mills. + + Topo! version 2.x: Tracks are implemented. + Topo! version 3.x: Reading of Tracks/Waypoints/Routes is + implemented. Also extracts Map Notes/ + Symbols/Text Labels as Waypoints. + + Copyright (C) 2005 Steve Chamberlin, slc at alum.mit.edu + Portions Copyright (C) 2006 Curtis E. Mills, archer at eskimo dot com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +/* + ***** This format has problems and the author hasn't returned emails + * on it, so we've set the format type to 'ff_type_internal' to make it + * disappear from the various lists... + */ + +/* + TPO format notes: + ----------------- + Most of the ASCII strings embedded in the text will have a + byte-count prepended to the string. Unknown yet whether other + fields have this same byte-count, but so far it doesn't look like + it. + + New format (3.x and later) files begin with a string byte-count + byte and then a string starting with "TOPO! Ver. 3.", like "TOPO! + Ver. 3.3.4". Can contain routes/tracks/waypoints, embedded + images, Map Notes, Symbols, Text Labels, Compass symbols, and + several others. + + Older (pre-3.0) format does not have the above string. Contains + only tracks. Waypoints are saved in a separate .TPG file. + + May contain these strings: + Frmt: String: + ----- -------------------------------- + 2.x "CTopoAzimuth" + 2.x "CTopoBookmark" + 2.x "CTopoGpsRoute". Saved in .tpg files (see tpg.c) + 2.x "CTopoRoute". The actual tracks we parse here. + 2.x "CTopoSymbol" + 2.x/3.x "CTopoText" + 2.x "CTopoWaypoint". Saved in .tpg files (see tpg.c) + 3.x "Notes" + 3.x "PNG." Embedded PNG image containing 2 rows of 40 + symbols each. Starts with signature: 89 50 4e 47 0d + 0a 1a 0a, ends with signature 49 45 4e 44 ae 42 60 82. + 3.x "shapes" + 3.x "arrows" + 3.x "recreation" +*/ + +#include "defs.h" +#include +#include +#include "jeeps/gpsmath.h" /* for datum conversions */ + +#define MYNAME "TPO" + +static char *dumpheader = NULL; +static char *output_state = NULL; + +/* +static +arglist_t tpo2_args[] = { + { "dumpheader", &dumpheader, "Display the file header bytes", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + { "state", &output_state, "State map format to write, default=CA", + "CA", ARGTYPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR +}; +*/ +// +// Note that we've disabled the write capabilites for the tpo2 +// format at present. The "testo" tests were failing on some +// platforms and there wasn't anyone willing to work on the problem. +// If this is fixed in the future we can go back to the tpo2_args[] +// above. +// +static +arglist_t tpo2_args[] = { + ARG_TERMINATOR +}; + +static +arglist_t tpo3_args[] = { + ARG_TERMINATOR +}; + + +static FILE *tpo_file_in; +static FILE *tpo_file_out; +//static short_handle mkshort_handle; + +static double output_track_lon_scale; +static double output_track_lat_scale; + +static unsigned int track_out_count; +static double first_track_waypoint_lat; +static double first_track_waypoint_lon; +static double track_length; +static double last_waypoint_x; +static double last_waypoint_y; +static double last_waypoint_z; + +/*******************************************************************************/ +/* READ */ +/*******************************************************************************/ + +static int +tpo_fread(void *buff, size_t size, size_t members, FILE * fp) +{ + size_t br; + + br = fread(buff, size, members, fp); + + if (br != members) { + fatal(MYNAME ": The input file does not look like a valid .TPO file.\n"); + } + + return (br); +} + +static double +tpo_fread_double(FILE *fp) +{ + unsigned char buf[8]; + tpo_fread(buf, 1, 8, fp); + return le_read_double(buf); +} + +static void +tpo_fwrite_double(double x, FILE *fp) +{ + unsigned char cbuf[8]; + le_write_double(cbuf,x); + fwrite(cbuf, 8, 1, fp); +} + +/* Define a global here that we can query from multiple places */ +float tpo_version = 0.0; + +/* tpo_check_version_string() + Check the first bytes of the file for a version 3.0 header. */ +static void +tpo_check_version_string() +{ + + unsigned char string_size; + char* string_buffer; + char* v3_id_string = "TOPO! Ver"; + + /* read the id string */ + tpo_fread(&string_size, 1, 1, tpo_file_in); + string_buffer = xmalloc(string_size+1); + tpo_fread(string_buffer, 1, string_size, tpo_file_in); + + /* terminate the string */ + string_buffer[string_size] = 0; + + /* check for the presence of a 3.0-style id string */ + if (strncmp(v3_id_string, string_buffer, strlen(v3_id_string)) == 0) + { +/* fatal(MYNAME ": gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); */ +//fprintf(stderr,"gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); + + fseek(tpo_file_in, -(string_size+1), SEEK_CUR); + xfree(string_buffer); + tpo_version = 3.0; /* Really any 3.x version */ + return; + + } + else { + /* We found a version 1.x or 2.x file */ + /* seek back to the beginning of the file */ + fseek(tpo_file_in, -(string_size+1), SEEK_CUR); + xfree(string_buffer); + tpo_version = 2.0; /* Really any 1.x or 2.x version */ + return; + } +} + +static void +/* tpo_dump_header_bytes(int header_size) + Write the first header_size bytes of the file to standard output + as a C array definition. */ +tpo_dump_header_bytes(int header_size) +{ + int i; + unsigned char* buffer = (unsigned char*)xmalloc(header_size); + + tpo_fread(buffer, 1, header_size, tpo_file_in); + + printf("unsigned char header_bytes[] = {\n"); + + for (i=0; irte_name = xstrdup(buff); + + /* zoom level 1-5 visibility flags */ + tpo_fread(&buff[0], 1, 10, tpo_file_in); + + /* 8 bytes of zeros, meaning unknown */ + tpo_fread(&buff[0], 1, 8, tpo_file_in); + + /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ + tpo_fread(&buff[0], 1, 4, tpo_file_in); + + /* read the position of the initial track point */ + /* for some very odd reason, signs on longitude are swapped */ + /* coordinates are in NAD27/CONUS datum */ + + /* 8 bytes - longitude, sign swapped */ + first_lon = tpo_fread_double(tpo_file_in); + + /* 8 bytes - latitude */ + first_lat = tpo_fread_double(tpo_file_in); + + /* swap sign before we do datum conversions */ + first_lon *= -1.0; + + /* 8 unknown bytes: seems to be some kind of bounding box info */ + tpo_fread(&buff[0], 1, 8, tpo_file_in); + + /* number of route points */ + tpo_fread(&buff[0], 1, 2, tpo_file_in); + waypoint_count = le_read16(&buff[0]); + + /* allocate temporary memory for the waypoint deltas */ + lon_delta = (short*)xmalloc(waypoint_count * sizeof(short)); + lat_delta = (short*)xmalloc(waypoint_count * sizeof(short)); + + for (j=0; jlatitude, + &waypoint_temp->longitude, + &amt, + 78); + + /* there is no elevation data for the waypoints */ + waypoint_temp->altitude = 0; + + track_add_wpt(track_temp, waypoint_temp); + } + + /* free temporary memory */ + xfree(lon_delta); + xfree(lat_delta); + } +} + + + + + +//------------------------------------------------------------------- +//------------------------------------------------------------------- + + + + + +// Read one 8-bit value from the input file. +// +// For version 3.x files. +// +int tpo_read_8() +{ + char val = 0; + + tpo_fread(&val, 1, 1, tpo_file_in); + return(val); +} + + + + + +// Read one 16-bit value in little-endian format from the input +// file. Takes care of processor endian-ness. +// +// For version 3.x files. +// +int tpo_read_16() +{ + unsigned char buf[2]; + int val = 0; + + tpo_fread(&buf[0], 1, 2, tpo_file_in); + val = le_read16(&buf[0]); + return(val); +} + + + + + +// Read one 32-bit value in little-endian format from the input +// file. Takes care of processor endian-ness. +// +// For version 3.x files. +// +int tpo_read_32() +{ + unsigned char buf[4]; + int val = 0; + + tpo_fread(&buf[0], 1, 4, tpo_file_in); + val = le_read32(&buf[0]); + return(val); +} + + + + + +// This will read 8/16/32 bits in little-endian format depending +// upon the value of the first byte. +// +// For version 3.x files. +// +int tpo_read_int() +{ + unsigned char val; + + + val = tpo_read_8(); + + switch (val) { + + case 0xff: // 32-bit value +//printf("Found 32-bit value indicator: %x\n", val); + return( tpo_read_32() ); + break; + + case 0xfe: // 16-bit value +//printf("Found 16-bit value indicator: %x\n", val); + return( tpo_read_16() ); + break; + + default: // 8-bit value +//printf("Found 8-bit value: %x\n", val); + return( (int)val ); + break; + } +} + + + + + +// Find variable block of interest in the file. Leaves the file +// pointer pointing after the two 4-byte type/pointer bytes. The +// file pointer should be pointing at the first data byte of the +// block after calling this, which is normally an 8/16/32-bit value +// specifying the number of elements in the block. +// +// Returns -1 if block not found +// 0 if block found +// +// For version 3.x files. +// +int tpo_find_block(unsigned int block_desired) +{ + int block_type; + int block_offset; + + + // Skip 512 byte fixed-length header + block_offset = 512; + + do { + + // Seek to offset from start of file + fseek(tpo_file_in, block_offset, SEEK_SET); + + // Read record type + block_type = tpo_read_32(); +//printf("Block: %08x\tat offset: %08x\n", block_type, block_offset); + + // Read offset to next record + block_offset = tpo_read_32(); + } + while (block_type != block_desired && block_offset != 0); + + if (block_type == block_desired) + return(0); + else + return(-1); +} + + + + + +// Convert lat/long to normal values, save in waypoint struct +// +// For version 3.x files. +// +waypoint *tpo_convert_ll(int lat, int lon) { + double latitude; + double longitude; + waypoint *waypoint_temp; + + + waypoint_temp = waypt_new(); + + latitude = (double)lat / 0x800000; + longitude = (double)lon / 0x800000; + +//printf("lat: %f\tlon: %f\n", latitude, longitude); + +/* + // Note: We shouldn't need this section of code as the version + // 3.x files are already in WGS84 datum. + // + // Convert incoming NAD27/CONUS coordinates to WGS84, Molodensky + // transform. + // + GPS_Math_Known_Datum_To_WGS84_M( + latitude, // Source latitude + longitude, // Source longitude + 0.0, // Source height (meters) + &waypoint_temp->latitude, // Dest latitude + &waypoint_temp->longitude, // Dest longitude + &height, // Dest height (meters) + 78); +*/ + + waypoint_temp->latitude = latitude; + waypoint_temp->longitude = longitude; + +//printf("lat: %f\tlon: %f\tNew Height: %f\n", waypoint_temp->latitude, waypoint_temp->longitude, height); + + return(waypoint_temp); +} + + + + + +// Track decoder for version 3.x files. This block contains tracks +// (called "freehand routes" or just "routes" in Topo). +// +void tpo_process_tracks(void) +{ + unsigned int track_count; + unsigned int ii; + + +//printf("Processing Tracks...\n"); + + // Find block 0x060000 (free-hand routes) + if (tpo_find_block(0x060000)) + return; + + // Read the number of tracks. Can be 8/16/32-bit value. + track_count = tpo_read_int(); + +//printf("Total Tracks: %d\n", track_count); + + if (track_count == 0) + return; + + // Read/process each track in the file + // + for (ii = 0; ii < track_count; ii++) { + unsigned int line_type; + unsigned int track_number; + unsigned int track_length; + unsigned int name_length; + char *track_name; + unsigned int track_byte_count; + int llvalid; + unsigned char *buf; + int lonscale; + int latscale; + int waypoint_count = 0; + int lat = 0; + int lon = 0; + unsigned int jj; + route_head* track_temp; + + + // Allocate the track struct + track_temp = route_head_alloc(); + track_add_head(track_temp); + +//UNKNOWN DATA LENGTH + line_type = tpo_read_int(); + + // Can be 8/16/32-bit value + track_number = tpo_read_int(); + + // Can be 8/16/32-bit value + track_length = tpo_read_int(); + +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + + if (name_length) { + track_name = xmalloc(name_length+1); + track_name[0] = '\0'; + tpo_fread(track_name, 1, name_length, tpo_file_in); + track_name[name_length] = '\0'; // Terminator + } + else { // Assign a generic track name + track_name = xmalloc(15); + sprintf(track_name, "TRK %d", ii+1); + } + track_temp->rte_name = track_name; +//printf("\nTrack Name: %s ", track_name); + + // Route description +// track_temp->rte_desc = NULL; + + // Route number + track_temp->rte_num = ii+1; + +//UNKNOWN DATA LENGTH + track_byte_count = tpo_read_int(); + + // Read the number of bytes specified for the track. These + // contain scaling factors, long/lat's, and offsets from + // those long/lat's. First will be a long/lat (8 bytes). + // Keep track of the bytes as we go so that we know how many + // we've read. We need to do this so that we start at the + // proper place for the next track. + + // Read the track bytes into a buffer + buf = xmalloc(track_byte_count); + tpo_fread(buf, 1, track_byte_count, tpo_file_in); + + latscale=0; + lonscale=0; + + // Process the track bytes + llvalid = 0; + for (jj = 0; jj < track_byte_count; ) { + waypoint* waypoint_temp; + + // Time to read a new latlong? + if (!llvalid) { + + lon = le_read32(buf+jj); + jj+=4; + + lat = le_read32(buf+jj); + jj+=4; + +//printf("L"); + + // Peek to see if next is a lonscale. Note that it + // can begin with 0x88, which is confusing. Here we + // allow up to 16-bits of offset, so two of the + // bytes must be 0x00 for us to recognize it. + if(jj+3>4]; + lat+=latscale*scarray[(buf[jj]&0xf)]; +//printf("."); + jj++; + + waypoint_temp = tpo_convert_ll(lat, lon); + route_add_wpt(track_temp, waypoint_temp); + waypoint_count++; + } + } + track_temp->rte_waypt_ct = waypoint_count; + + xfree(buf); + } +//printf("\n"); +} + + + + + +// Global index to waypoints, needed for routes, filled in by +// tpo_process_waypoints. +// +// For version 3.x files. +// +waypoint** tpo_wp_index; +unsigned int tpo_index_ptr = 0; + + + + + +// Waypoint decoder for version 3.x files. +// +void tpo_process_waypoints(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Waypoints...\n"); + + // Find block 0x0e0000 (GPS-Waypoints) + if (tpo_find_block(0x0e0000)) + return; + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Total Waypoints: %d\n", waypoint_count); + + // Fetch storage for the waypoint index (needed later for + // routes) + tpo_wp_index = (waypoint **)xmalloc(sizeof(waypoint *) * waypoint_count); + + if (waypoint_count == 0) + return; + + // Read/process each waypoint in the file + for (ii = 0; ii < waypoint_count; ii++) { + waypoint* waypoint_temp; + waypoint* waypoint_temp2; + unsigned int name_length; + char *waypoint_name; + int lat; + int lon; + int altitude; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); // 0x00 + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); // 0x00 + +//UNKNOWN DATA LENGTH + // Fetch name length + name_length = tpo_read_int(); +//printf("\nName Length: %d\n", name_length); + if (name_length) { + waypoint_name = xmalloc(name_length+1); + waypoint_name[0] = '\0'; + tpo_fread(waypoint_name, 1, name_length, tpo_file_in); + waypoint_name[name_length] = '\0'; // Terminator + } + else { // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "WPT %d", ii+1); + } +//printf("\tWaypoint Name: %s\n", waypoint_name); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = tpo_read_32(); + lat = tpo_read_32(); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign the waypoint name + waypoint_temp->shortname = waypoint_name; + + // Grab the altitude in meters + altitude = tpo_read_32(); + if (altitude == 0xfffd000c) // Unknown altitude + altitude = 0; + waypoint_temp->altitude = altitude / 100; // Meters +//printf("\tAltitude: %1.0f meters\n", waypoint_temp->altitude); + +//UNKNOWN DATA LENGTH + // Fetch comment length + name_length = tpo_read_int(); +//printf("\tComment length: %d\n", name_length); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + tpo_fread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; +//printf("\tComment: %s\n", waypoint_name); + } + else { +// waypoint_temp->description = NULL; + } + +// waypoint_temp->notes = NULL; +// waypoint_temp->url = NULL; +// waypoint_temp->url_link_text = NULL; + + // For routes (later), we need a duplicate of each waypoint + // indexed by the order we read them in. + waypoint_temp2 = waypt_dupe(waypoint_temp); + + // Attach the copy to our index + tpo_wp_index[tpo_index_ptr++] = waypoint_temp2; + + // Add the original waypoint to the chain of waypoints + waypt_add(waypoint_temp); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void)tpo_read_8(); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void)tpo_read_8(); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void)tpo_read_8(); + +//UNKNOWN DATA LENGTH +// (void)tpo_read_int(); + (void)tpo_read_8(); + } +} + + + + + +// Map Notes decoder for version 3.x files. +// +void tpo_process_map_notes(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Map Notes...\n"); + + // Find block 0x090000 (Map Notes) + if (tpo_find_block(0x090000)) { + return; + } + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Elements: %d\n", waypoint_count); + + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int lat; + int lon; + unsigned int name_length; + char *waypoint_name; + waypoint* waypoint_temp; + unsigned int num_bytes; + unsigned int jj; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = tpo_read_32(); + lat = tpo_read_32(); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "NOTE %d", ii+1); +//printf("Waypoint Name: %s\t\t", waypoint_name); + waypoint_temp->shortname = waypoint_name; + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + // Fetch comment length + name_length = tpo_read_int(); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + tpo_fread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; +//printf("Comment: %s\n", comment); + } + else { +// waypoint_temp->description = NULL; + } + +// waypoint_temp->url_link_text = NULL; + + // Length of text for external path. If non-zero, skip past + // the text. +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); +//printf("name_length: %x\n", name_length); + if (name_length) { + char *notes; + + notes = xmalloc(name_length+1); + notes[0] = '\0'; + tpo_fread(notes, 1, name_length, tpo_file_in); + notes[name_length] = '\0'; // Terminator + waypoint_temp->url = notes; +//printf("Notes: %s\n", notes); + } + + // Length of text for image path. If non-zero, skip past + // the text. +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + if (name_length) { + char *notes; + + notes = xmalloc(name_length+1); + notes[0] = '\0'; + tpo_fread(notes, 1, name_length, tpo_file_in); + notes[name_length] = '\0'; // Terminator + waypoint_temp->url = notes; +//printf("Notes: %s\n", notes); + } + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + // Number of bytes to skip until next element or end of + // block. May be 8/16/32 bits. + num_bytes = tpo_read_int(); +//printf("num_bytes: %x\n", num_bytes); + for (jj = 0; jj < num_bytes; jj++) { + (void)tpo_read_8(); // Skip bytes + } + + // Can be 8/16/32 bits + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } +} + + + + + +// Symbols decoder for version 3.x files. +// +void tpo_process_symbols(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Symbols...\n"); + + // Find block 0x040000 (Symbols) + if (tpo_find_block(0x040000)) + return; + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Elements: %d\n", waypoint_count); + + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int lat; + int lon; + char *waypoint_name; + waypoint* waypoint_temp; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = tpo_read_32(); + lat = tpo_read_32(); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "SYM %d", ii+1); +//printf("Waypoint Name: %s\n", waypoint_name); + waypoint_temp->shortname = waypoint_name; + +// waypoint_temp->description = NULL; +// waypoint_temp->notes = NULL; +// waypoint_temp->url = NULL; +// waypoint_temp->url_link_text = NULL; + + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } +} + + + + + +// Text Labels decoder for version 3.x files. +// +void tpo_process_text_labels(void) +{ + unsigned int waypoint_count; + unsigned int ii; + + +//printf("Processing Text Labels...\n"); + + // Find block 0x080000 (Text Labels) + if (tpo_find_block(0x080000)) + return; + + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); + +//printf("Elements: %d\n", waypoint_count); + + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int jj; + int lat; + int lon; + unsigned int name_length; + char *waypoint_name; + waypoint* waypoint_temp; + + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + + lon = tpo_read_32(); + lat = tpo_read_32(); + + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); + + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "TXT %d", ii+1); +//printf("Waypoint Name: %s\t\t", waypoint_name); + waypoint_temp->shortname = waypoint_name; + + for (jj = 0; jj < 16; jj++) { +//UNKNOWN DATA LENGTH + (void)tpo_read_8(); + } + + // Fetch comment length +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + tpo_fread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; +//printf("Comment: %s\n", comment); + } + else { +// waypoint_temp->description = NULL; + } + +// waypoint_temp->notes = NULL; +// waypoint_temp->url = NULL; +// waypoint_temp->url_link_text = NULL; + + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } +} + + + + + +// Route decoder for version 3.x files. +// +// We depend on tpo_wp_index[] having been malloc'ed and filled-in +// with pointers to waypoint objects by tpo_process_waypoints() +// function above. +// +void tpo_process_routes(void) +{ + unsigned int route_count; + unsigned int ii; + + +//printf("Processing Routes...\n"); + + // Find block 0x0f0000 (GPS-Routes) + if (tpo_find_block(0x0f0000)) + return; + + // Read the number of routes. 8/16/32-bit value + route_count = tpo_read_int(); + +//printf("Total Routes: %d\n", route_count); + + if (route_count == 0) + return; + + // Read/process each route in the file + // + for (ii = 0; ii < route_count; ii++) { + unsigned int name_length = 0; + char *route_name; + unsigned int jj; + unsigned int waypoint_cnt; + route_head* route_temp; + + + // Allocate the route struct + route_temp = route_head_alloc(); + route_add_head(route_temp); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + (void)tpo_read_int(); + +//UNKNOWN DATA LENGTH + // Fetch name length + name_length = tpo_read_int(); + if (name_length) { + route_name = xmalloc(name_length+1); + route_name[0] = '\0'; + tpo_fread(route_name, 1, name_length, tpo_file_in); + route_name[name_length] = '\0'; // Terminator + } + else { // Assign a generic route name + route_name = xmalloc(15); + sprintf(route_name, "RTE %d", ii+1); + } + route_temp->rte_name = route_name; +//printf("Route Name: %s\n", route_name); + +//UNKNOWN DATA LENGTH + // Comment? + (void)tpo_read_int(); +// (void)tpo_read_8(); +// route_temp->rte_desc = NULL; + + route_temp->rte_num = ii+1; + + // Fetch the number of waypoints in this route. 8/16/32-bit + // value. + waypoint_cnt = tpo_read_int(); + + route_temp->rte_waypt_ct = waypoint_cnt; + + // Run through the list of waypoints, look up each in our + // index, then add the waypoint to this route. + // + for (jj = 0; jj < waypoint_cnt; jj++) { + waypoint* waypoint_temp; + unsigned char val; + + +//UNKNOWN DATA LENGTH + // Fetch the index to the waypoint + val = tpo_read_int(); +//printf("val: %x\t\t", val); + + // Duplicate a waypoint from our index of waypoints. + waypoint_temp = waypt_dupe(tpo_wp_index[val-1]); + + // Add the waypoint to the route + route_add_wpt(route_temp, waypoint_temp); + } +//printf("\n"); + } + + // Free the waypoint index, we don't need it anymore. + for (ii = 0; ii < tpo_index_ptr; ii++) { + if (tpo_wp_index[ii]->shortname) + xfree(tpo_wp_index[ii]->shortname); + if (tpo_wp_index[ii]->description) + xfree(tpo_wp_index[ii]->description); + xfree(tpo_wp_index[ii]); + } + + // Free the index array itself + xfree(tpo_wp_index); +} + + + + + +// Compass decoder for version 3.x files. +// +void tpo_process_compass(void) +{ + + // Not implemented yet +} + + + + + +// Decoder for version 3.x files. These files have "tracks" +// (called "freehand routes" or just "routes" in Topo), "waypoints", +// and "gps-routes". We intend to read all three types. +// +void tpo_read_3_x(void) +{ + + if (doing_trks) { +//printf("Processing Tracks\n"); + tpo_process_tracks(); + } + + if (doing_wpts || doing_rtes) { +//printf("Processing Waypoints\n"); + tpo_process_waypoints(); + } + + if (doing_rtes) { + // + // Note: To process routes we _MUST_ process waypoints + // first! This creates the index of waypoints that we need + // for routes. + // +//printf("Processing Routes\n"); + tpo_process_routes(); + } + + if (doing_wpts) { + // + // Other blocks in the file have waypoint-type information + // in them. Map Notes, Symbols, and Text Labels. We + // process those here and add them to the end of the + // waypoint list. + // +//printf("Processing Map Notes\n"); + tpo_process_map_notes(); + +//printf("Processing Symbols\n"); + tpo_process_symbols(); + +//printf("Processing Text Labels\n"); + tpo_process_text_labels(); + +//printf("Processing Compass Symbols\n"); +// tpo_process_compass(); + + } +} + + + + + +//------------------------------------------------------------------- +//------------------------------------------------------------------- + + + + + +static void +tpo_read(void) +{ + + if (tpo_version == 2.0) { +//printf("\nFound a version 2.x file\n"); + tpo_read_2_x(); + } + else if (tpo_version == 3.0) { +//printf("\nFound a version 3.x file\n"); + tpo_read_3_x(); + } + else { + fatal(MYNAME ": gpsbabel can only read TPO versions through 3.x.x\n"); + } +} + + + + + +/*******************************************************************************/ +/* WRITE */ +/*******************************************************************************/ + +/* tpo_write_file_header() + Write the appropriate header for the desired TOPO! state. + + National Geographic sells about 75 different state and regional software + programs called TOPO! that use the TPO format. Each one uses a different + header data sequence. The header contains the name of the state maps, as well + as some map scaling information and other data. In most cases, you can't open + a TPO file created by a different state/regional version of TOPO! than the one + you're using yourself. When writing a TPO file, it is therefore necessary to + specify what TOPO! state product to create the file for. I believe that the + TOPO! regional products can open TPO files created by the TOPO! state products + as long as the track data is within the area covered by the regional product. + As a result, it's only necessary to decide what state product output format to + use. + + TO ADD SUPPORT FOR ANOTHER STATE: + 1. Obtain an example .tpo file generated by the state product for which you wish + to add support. National Geographic MapXchange (http://maps.nationalgeographic.com/topo/search.cfm) + is a good source of .tpo files. + 2. Run gpsbabel using the "dumpheader" option of the TPO format converter, and + specifying a dummy output file. For example: + gpsbabel -t -i tpo,dumpheader=1 -f sample_file.tpo -o csv -F dummy.txt + This will write a snippet of C code containing the header bytes to the shell window. + 3. Add a new if() clause to tpo_write_file_header(). Copy the header bytes definition + from the previous step. + 4. Recompile gpsbabel. + 5. You should now be able write TPO ouput in the new state's format. For example, if + you added support for Texas: + gpsbabel -t -i gpx -f input.gpx -o tpo,state="TX" -F output.tpo */ +static void +tpo_write_file_header() +{ + /* force upper-case state name */ + strupper(output_state); + + if (strncmp("CA", output_state, 2) == 0) { + + unsigned char header_bytes[] = { + 0x18, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, + 0x6E, 0x69, 0x61, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x64, 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, + 0x66, 0x03, 0x43, 0x41, 0x31, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x27, 0x43, 0x3A, 0x5C, + 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, + 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, + 0x44, 0x41, 0x54, 0x41, 0x5C, 0x43, 0x41, 0x5F, + 0x44, 0x30, 0x31, 0x5C, 0x20, 0x43, 0x3A, 0x5C, + 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, + 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, + 0x44, 0x41, 0x54, 0x41, 0x5C, 0x12, 0x43, 0x3A, + 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, 0x54, + 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5C, + 0x00, 0x00, 0x00, 0xDC, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x34, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x30, 0x35, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, + 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x31, 0x30, 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x30, 0x39, 0x30, 0x39, + 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0xBC, 0x23, + 0x63, 0xB5, 0xF9, 0x3A, 0x50, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, 0x22, 0xE2, + 0xE6, 0x54, 0x32, 0x28, 0x22, 0x40, 0x0A, 0x43, + 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, + 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, + 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x43, 0x41, 0x31, + 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, + 0x4C, 0xAF, 0x02, 0x15, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x40, 0x84, 0x00, 0x78, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, + 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, + 0x0D, 0x00, 0x02, 0x44, 0x41, 0x23, 0x01, 0x6C, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, + 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, + 0x02, 0x44, 0x46, 0x00, 0x01, 0x40, 0x01, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, + 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, + 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, + 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, + 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, + 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, + 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, + 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, + 0x00, 0x01, 0x00, 0x28, 0x00 + }; + + fwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); + } + else if (strncmp("CT", output_state, 2) == 0 || + strncmp("MA", output_state, 2) == 0 || + strncmp("ME", output_state, 2) == 0 || + strncmp("NJ", output_state, 2) == 0 || + strncmp("NH", output_state, 2) == 0 || + strncmp("NY", output_state, 2) == 0 || + strncmp("RI", output_state, 2) == 0 || + strncmp("VT", output_state, 2) == 0) { + /* These 8 states are all covered in a single "Northeast" title */ + + unsigned char header_bytes[] = { + 0x1E, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, + 0x41, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x64, + 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, 0x66, 0x03, + 0x4E, 0x45, 0x31, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x50, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0B, 0x44, 0x3A, 0x5C, 0x4E, 0x45, + 0x31, 0x5F, 0x44, 0x30, 0x31, 0x5C, 0x12, 0x43, + 0x3A, 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, + 0x54, 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, + 0x5C, 0x12, 0x45, 0x3A, 0x5C, 0x54, 0x4F, 0x50, + 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, 0x44, + 0x41, 0x54, 0x41, 0x5C, 0x00, 0x00, 0x00, 0xFF, + 0x18, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x34, 0x30, 0x34, 0x30, 0x35, 0x30, 0x35, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x30, 0x33, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x30, 0x32, 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, + 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, + 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x4E, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, + 0x10, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x48, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, + 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, + 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, + 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x4E, 0x45, 0x31, + 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, + 0x4C, 0x68, 0x03, 0x16, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2C, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x40, 0x8C, 0x00, 0x64, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, + 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, + 0x0D, 0x00, 0x02, 0x44, 0x41, 0x0B, 0x01, 0x6C, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, + 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, + 0x02, 0x44, 0x46, 0xEA, 0x00, 0x40, 0x01, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, + 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, + 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, + 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, + 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, + 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, + 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, + 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, + 0x00, 0x01, 0x00, 0x28, 0x00 + }; + + fwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); + } + + else { + fatal(MYNAME ": writing ouput for state \"%s\" is not currently supported.\n", output_state); + } +} + +static void +tpo_track_hdr(const route_head *rte) +{ + double amt; + unsigned char temp_buffer[8]; + unsigned char visibility_flags[] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; + unsigned char unknown1[] = { 0xFF, 0x00, 0x00, 0x00 }; + unsigned char bounding_box[8] = { 0x00, 0x80, 0x00, 0x80, 0xFF, 0x7F, 0xFF, 0x7F }; + + waypoint* first_track_waypoint = (waypoint*) QUEUE_FIRST(&rte->waypoint_list); + + /* zoom level 1-5 visibility flags */ + fwrite(visibility_flags, 1, sizeof(visibility_flags), tpo_file_out); + + /* 8 bytes of zeros, meaning unknown */ + memset(temp_buffer, 0, sizeof(temp_buffer)); + fwrite(temp_buffer, 1, sizeof(temp_buffer), tpo_file_out); + + /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ + fwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); + + /* the starting point of the route */ + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + first_track_waypoint->latitude, + first_track_waypoint->longitude, + first_track_waypoint->altitude, + &first_track_waypoint_lat, + &first_track_waypoint_lon, + &amt, + 78); + + /* swap the sign back *after* the datum conversion */ + first_track_waypoint_lon *= -1.0; + + /* Compute this track's scaling factors: Used for scaling each track point and then + later written out to the track footer. These are approximately the ratios between + pixels and degrees when viewing the 1:24000 map in TOPO!. In practice, it doesn't + appear to be necessary that they be correct, as long as the same values are used + for doing the scaling and for writing into the track footer data. */ + output_track_lat_scale = 4.8828125e-005; /* TOPO! appears to use a constant lat scale */ + output_track_lon_scale = output_track_lat_scale / cos(GPS_Math_Deg_To_Rad(first_track_waypoint_lat)); + + /* 8 bytes - longitude */ + tpo_fwrite_double(first_track_waypoint_lon, tpo_file_out); + + /* 8 bytes - latitude */ + tpo_fwrite_double(first_track_waypoint_lat, tpo_file_out); + + /* 8 bytes: seems to be bounding box info */ + fwrite(bounding_box, 1, sizeof(bounding_box), tpo_file_out); + + /* number of route points */ + le_write16(temp_buffer, rte->rte_waypt_ct); + fwrite(temp_buffer, 1, 2, tpo_file_out); + + /* initialize the track length computation */ + track_length = 0; + GPS_Math_WGS84LatLonH_To_XYZ( + first_track_waypoint->latitude, + first_track_waypoint->longitude, + 0.0, + &last_waypoint_x, + &last_waypoint_y, + &last_waypoint_z); +} + +static void +tpo_track_disp(const waypoint *waypointp) +{ + double lat, lon, amt, x, y, z; + short lat_delta, lon_delta; + unsigned char temp_buffer[2]; + +/* fprintf(stderr, "%f/%f\n", waypointp->latitude, waypointp->longitude); */ + + /* convert lat/lon position to XYZ meters */ + GPS_Math_WGS84LatLonH_To_XYZ( + waypointp->latitude, + waypointp->longitude, + 0.0, + &x, + &y, + &z); + + /* increase the track length by the 3D length of last track segment in feet */ + track_length += METERS_TO_FEET(sqrt( + (x - last_waypoint_x) * (x - last_waypoint_x) + + (y - last_waypoint_y) * (y - last_waypoint_y) + + (z - last_waypoint_z) * (z - last_waypoint_z))); + last_waypoint_x = x; + last_waypoint_y = y; + last_waypoint_z = z; + + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + waypointp->latitude, + waypointp->longitude, + waypointp->altitude, + &lat, + &lon, + &amt, + 78); + + /* swap the sign back *after* the datum conversion */ + lon *= -1.0; + + /* longitude delta from first route point */ + lon_delta = (short)((first_track_waypoint_lon - lon) / output_track_lon_scale); + le_write16(temp_buffer, lon_delta); + fwrite(temp_buffer, 1, 2, tpo_file_out); + + /* latitude delta from first route point */ + lat_delta = (short)((first_track_waypoint_lat - lat) / output_track_lat_scale); + le_write16(temp_buffer, lat_delta); + +/* +fprintf(stderr, "%f %f: %x %x - %f %f %f / %f\n", lon, lat, lon_delta, lat_delta, first_track_waypoint_lat, lat, output_track_lat_scale, (first_track_waypoint_lat - lat) ); +*/ + + fwrite(temp_buffer, 1, 2, tpo_file_out); +} + +static void +tpo_track_tlr(const route_head *rte) +{ + unsigned char temp_buffer[4]; + + unsigned char unknown1[] = { 0x06, 0x00 }; + + unsigned char continue_marker[] = { 0x01, 0x80 }; + unsigned char end_marker[] = { 0x00, 0x00 }; + + /* pixel to degree scaling factors */ + tpo_fwrite_double(output_track_lon_scale, tpo_file_out); + tpo_fwrite_double(output_track_lat_scale, tpo_file_out); + + /* 4 bytes: the total length of the route */ + le_write32(temp_buffer, (unsigned int)track_length); + fwrite(temp_buffer, 1, 4, tpo_file_out); + + /* 2 unknown bytes */ + fwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); + + /* the last track ends with 0x0000 instead of 0x0180 */ + track_out_count++; + if (track_out_count == track_count()) { + fwrite(end_marker, 1, sizeof(end_marker), tpo_file_out); + } else { + fwrite(continue_marker, 1, sizeof(continue_marker), tpo_file_out); + } +} + +static void +tpo_wr_init(const char *fname) +{ + if (doing_wpts || doing_rtes) + { + fatal(MYNAME ": this file format only supports tracks, not waypoints or routes.\n"); + } + + tpo_file_out = xfopen(fname, "wb", MYNAME); + tpo_write_file_header(); +} + +static void +tpo_wr_deinit(void) +{ + /* the file footer is six bytes of zeroes */ + unsigned char file_footer_bytes[6]; + memset(file_footer_bytes, 0, sizeof(file_footer_bytes)); + fwrite(file_footer_bytes, 1, sizeof(file_footer_bytes), tpo_file_out); + + fclose(tpo_file_out); +} + +static void +tpo_write(void) +{ + unsigned char buffer[8]; + unsigned char unknown1[] = { 0xFF, 0xFF, 0x01, 0x00 }; + + char* chunk_name = "CTopoRoute"; + int chunk_name_length = strlen(chunk_name); + + /* write the total number of tracks */ + le_write16(buffer, track_count()); + fwrite(buffer, 1, 2, tpo_file_out); + + /* 4 unknown bytes */ + fwrite(unknown1, 1, 4, tpo_file_out); + + /* chunk name: "CTopoRoute" */ + le_write16(buffer, chunk_name_length); + fwrite(buffer, 1, 2, tpo_file_out); + fwrite(chunk_name, 1, chunk_name_length, tpo_file_out); + + track_out_count = 0; + track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp); +} + +/* TPO 2.x format can read tracks only */ +ff_vecs_t tpo2_vecs = { + ff_type_file, /* ff_type_internal */ +/* { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */ + { ff_cap_none | ff_cap_none, ff_cap_read, ff_cap_none | ff_cap_none }, + tpo_rd_init, + tpo_wr_init, + tpo_rd_deinit, + tpo_wr_deinit, + tpo_read, + tpo_write, + NULL, + tpo2_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + +/* TPO 3.x format can read waypoints/tracks/routes */ +ff_vecs_t tpo3_vecs = { + ff_type_file, /* ff_type_internal */ + { ff_cap_read, ff_cap_read, ff_cap_read }, + tpo_rd_init, + tpo_wr_init, + tpo_rd_deinit, + tpo_wr_deinit, + tpo_read, + tpo_write, + NULL, + tpo3_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; + diff --git a/tpo.testo.patch b/tpo.testo.patch new file mode 100644 index 000000000..1dec24cec --- /dev/null +++ b/tpo.testo.patch @@ -0,0 +1,27 @@ +Index: testo +=================================================================== +RCS file: /cvsroot/gpsbabel/gpsbabel/testo,v +retrieving revision 1.110 +diff -p -u -r1.110 testo +--- testo 26 Oct 2005 23:11:21 -0000 1.110 ++++ testo 31 Oct 2005 22:23:33 -0000 +@@ -172,6 +172,19 @@ ${PNAME} -i tpg -f ${TMPDIR}/geo.tpg -o + ${PNAME} -i tpg -f reference/tpg.tpg -o mxf -F ${TMPDIR}/topo.mxf + compare ${TMPDIR}/tpg.mxf ${TMPDIR}/topo.mxf + ++# TPO (NG Topo!) file format ++# This is hard to test because the datum conversions create minute ++# inconsistencies in the coordinates. We have four reference files: ++# sample1.tpo, sample1.gpx, sample2.gpx, and sample2.tpo. These are ++# used to check the conversion to and from TPO format. ++rm -f ${TMPDIR}/sample1.gpx ${TMPDIR}/sample2.tpo ++${PNAME} -t -i tpo -f reference/track/sample1.tpo -o gpx -F ${TMPDIR}/sample1.gpx ++compare ${TMPDIR}/sample1.gpx reference/track/sample1.gpx ++${PNAME} -t -i gpx -f reference/track/sample2.gpx -o tpo -F ${TMPDIR}/sample2.tpo ++bincompare ${TMPDIR}/sample2.tpo reference/track/sample2.tpo ++ ++ ++ + # OZI (OziExplorer 1.1) file format + rm -f ${TMPDIR}/oz.wpt ${TMPDIR}/ozi.wpt + ${PNAME} -i ozi -f reference/ozi.wpt -o ozi -F ${TMPDIR}/oz.wpt diff --git a/trackfilter.c b/trackfilter.c index acd1bb43b..7b5cf60a6 100644 --- a/trackfilter.c +++ b/trackfilter.c @@ -2,7 +2,7 @@ Track manipulation filter - Copyright (C) 2005 Olaf Klein, o.b.klein@t-online.de + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,58 +19,91 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - /* 2005-07-20: implemented interval option from Etienne Tasse 2005-07-26: implemented range option 2005-07-26: implemented move option 2005-07-26: implemented merge option 2005-07-29: warning fixes + 2005-08-01: Add 'static' qualifier when we can (RJL) + 2005-10-04: Add filterdefs to hold protos for filter functions... (RJL) + 2005-10-04: Fix range-check max. value; exit filter, if no more tracks left + 2006-04-06: Add fix, course, and speed options + 2006-06-01: Add name option */ -#include -#include #include #include "defs.h" +#include "filterdefs.h" #include "strptime.h" +#include "grtcirc.h" +#if FILTERS_ENABLED #define MYNAME "trackfilter" #define TRACKFILTER_PACK_OPTION "pack" #define TRACKFILTER_SPLIT_OPTION "split" +#define TRACKFILTER_SDIST_OPTION "sdistance" #define TRACKFILTER_TITLE_OPTION "title" #define TRACKFILTER_MERGE_OPTION "merge" +#define TRACKFILTER_NAME_OPTION "name" #define TRACKFILTER_STOP_OPTION "stop" #define TRACKFILTER_START_OPTION "start" #define TRACKFILTER_MOVE_OPTION "move" +#define TRACKFILTER_FIX_OPTION "fix" +#define TRACKFILTER_COURSE_OPTION "course" +#define TRACKFILTER_SPEED_OPTION "speed" #undef TRACKF_DBG static char *opt_merge = NULL; static char *opt_pack = NULL; static char *opt_split = NULL; +static char *opt_sdistance = NULL; static char *opt_move = NULL; static char *opt_title = NULL; static char *opt_start = NULL; static char *opt_stop = NULL; +static char *opt_fix = NULL; +static char *opt_course = NULL; +static char *opt_speed = NULL; +static char *opt_name = NULL; static arglist_t trackfilter_args[] = { {TRACKFILTER_MOVE_OPTION, &opt_move, - "Correct trackpoint timestamps by a delta", NULL, ARGTYPE_STRING}, + "Correct trackpoint timestamps by a delta", NULL, ARGTYPE_STRING, + ARG_NOMINMAX}, {TRACKFILTER_PACK_OPTION, &opt_pack, - "Pack all tracks into one", NULL, ARGTYPE_BOOL}, + "Pack all tracks into one", NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, {TRACKFILTER_SPLIT_OPTION, &opt_split, - "Split track by date or by time interval (see README)", NULL, ARGTYPE_STRING}, + "Split by date or time interval (see README)", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {TRACKFILTER_SDIST_OPTION, &opt_sdistance, + "Split by distance", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, {TRACKFILTER_MERGE_OPTION, &opt_merge, - "Merge multiple tracks for the same way", NULL, ARGTYPE_STRING}, + "Merge multiple tracks for the same way", NULL, ARGTYPE_STRING, + ARG_NOMINMAX}, + {TRACKFILTER_NAME_OPTION, &opt_name, + "Use only track(s) where title matches given name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX}, {TRACKFILTER_START_OPTION, &opt_start, - "Use only track points after this timestamp", NULL, ARGTYPE_INT}, + "Use only track points after this timestamp", NULL, ARGTYPE_INT, + ARG_NOMINMAX}, {TRACKFILTER_STOP_OPTION, &opt_stop, - "Use only track points before this timestamp", NULL, ARGTYPE_INT}, + "Use only track points before this timestamp", NULL, ARGTYPE_INT, + ARG_NOMINMAX}, {TRACKFILTER_TITLE_OPTION, &opt_title, - "Basic title for new track(s)", NULL, ARGTYPE_STRING}, - {0, 0, 0, 0, 0} + "Basic title for new track(s)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {TRACKFILTER_FIX_OPTION, &opt_fix, + "Synthesize GPS fixes (PPS, DGPS, 3D, 2D, NONE)", NULL, + ARGTYPE_STRING, ARG_NOMINMAX }, + {TRACKFILTER_COURSE_OPTION, &opt_course, "Synthesize course", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {TRACKFILTER_SPEED_OPTION, &opt_speed, "Synthesize speed", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; @@ -85,20 +118,7 @@ static trkflt_t *track_list = NULL; static int track_ct = 0; static int track_pts = 0; static int opt_interval = 0; - -/******************************************************************************* -* dummy callbacks for track_disp_all -*******************************************************************************/ - -static void -trackfilter_noop_w(const waypoint *w) -{ -} - -static void -trackfilter_noop_t(const route_head *h) -{ -} +static int opt_distance = 0; /******************************************************************************* * helpers @@ -139,19 +159,20 @@ trackfilter_parse_time_opt(const char *arg) } switch(tolower(c)) { - case 'd': seconds = (24 * 60 * 60); break; - case 'h': seconds = (60 * 60); break; + case 'd': seconds = SECONDS_PER_DAY; break; + case 'h': seconds = SECONDS_PER_HOUR; break; case 'm': seconds = 60; break; case 's': seconds = 1; break; case '+': sign = +1; continue; case '-': sign = -1; continue; default: fatal(MYNAME "-time: invalid character in time option!\n"); } - t0 += (t1 * seconds); + t0 += (t1 * seconds * sign); + sign = +1; t1 = 0; } t0 += t1; - return t0 * sign; + return t0; } static int @@ -172,6 +193,31 @@ trackfilter_merge_qsort_cb(const void *a, const void *b) return wa->creation_time - wb->creation_time; } +static fix_type +trackfilter_parse_fix() +{ + if ( !opt_fix ) { + return fix_unknown; + } + if ( !case_ignore_strcmp( opt_fix, "pps" )) { + return fix_pps; + } + if ( !case_ignore_strcmp( opt_fix, "dgps" )) { + return fix_dgps; + } + if ( !case_ignore_strcmp( opt_fix, "3d" )) { + return fix_3d; + } + if ( !case_ignore_strcmp( opt_fix, "2d" )) { + return fix_2d; + } + if ( !case_ignore_strcmp( opt_fix, "none" )) { + return fix_none; + } + fatal( MYNAME ": invalid fix type\n" ); + return 0; +} + static void trackfilter_fill_track_list_cb(const route_head *track) /* callback for track_disp_all */ { @@ -185,6 +231,16 @@ trackfilter_fill_track_list_cb(const route_head *track) /* callback for track_d return; } + if (opt_name != NULL) + { + if ((track->rte_name == NULL) || + (case_ignore_str_match(track->rte_name, opt_name) == 0)) + { + track_del_head((route_head *)track); + return; + } + } + track_list[track_ct].track = (route_head *)track; i = 0; @@ -368,7 +424,7 @@ trackfilter_merge(void) { wpt = (waypoint *)elem; buff[j++] = waypt_dupe(wpt); - route_del_wpt(track, wpt); + track_del_wpt(track, wpt); } if (track != master) /* i > 0 */ track_del_head(track); @@ -416,17 +472,19 @@ trackfilter_split(void) queue *elem, *tmp; int i, j; float interval = -1; + float distance = -1; if (count <= 1) return; /* check additional options */ - opt_interval = (0 != strcmp(opt_split, TRACKFILTER_SPLIT_OPTION)); + opt_interval = (opt_split && (strlen(opt_split) > 0) && (0 != strcmp(opt_split, TRACKFILTER_SPLIT_OPTION))); + opt_distance = (opt_sdistance && (strlen(opt_sdistance) > 0) && (0 != strcmp(opt_sdistance, TRACKFILTER_SDIST_OPTION))); if (opt_interval != 0) { float base; - char dhms; + char unit; switch(strlen(opt_split)) { @@ -435,16 +493,16 @@ trackfilter_split(void) break; /* ? */ case 1: - dhms = *opt_split; + unit = *opt_split; interval = 1; break; default: - i = sscanf(opt_split,"%f%c", &interval, &dhms); + i = sscanf(opt_split,"%f%c", &interval, &unit); if (i == 0) { /* test reverse order */ - i = sscanf(opt_split,"%c%f", &dhms, &interval); + i = sscanf(opt_split,"%c%f", &unit, &interval); } if ((i != 2) || (interval <= 0)) { @@ -453,7 +511,7 @@ trackfilter_split(void) break; } - switch(tolower(dhms)) + switch(tolower(unit)) { case 's': base = 1; @@ -472,11 +530,59 @@ trackfilter_split(void) break; } #ifdef TRACKF_DBG - printf(MYNAME ": dhms \"%c\", interval %g -> %g\n", dhms, interval, base * interval); + printf(MYNAME ": unit \"%c\", interval %g -> %g\n", unit, interval, base * interval); #endif interval *= base; } + if (opt_distance != 0) + { + float base; + char unit; + + switch(strlen(opt_sdistance)) + { + case 0: + fatal(MYNAME ": No distance specified.\n"); + break; /* ? */ + + case 1: + unit = *opt_sdistance; + distance = 1; + break; + + default: + i = sscanf(opt_sdistance,"%f%c", &distance, &unit); + if (i == 0) + { + /* test reverse order */ + i = sscanf(opt_sdistance,"%c%f", &unit, &distance); + } + if ((i != 2) || (distance <= 0)) + { + fatal(MYNAME ": invalid distance specified, must be one a positive number.\n"); + } + break; + } + + switch(tolower(unit)) + { + case 'k': /* kilometers */ + base = 0.6214; + break; + case 'm': /* miles */ + base = 1; + break; + default: + fatal(MYNAME ": invalid distance specified, must be one of [km].\n"); + break; + } +#ifdef TRACKF_DBG + printf(MYNAME ": unit \"%c\", distance %g -> %g\n", unit, distance, base * distance); +#endif + distance *= base; + } + trackfilter_split_init_rte_name(master, track_list[0].first_time); buff = (waypoint **) xcalloc(count, sizeof(*buff)); @@ -494,7 +600,7 @@ trackfilter_split(void) { int new_track_flag; - if (opt_interval == 0) + if ((opt_interval == 0) && (opt_distance == 0)) { struct tm t1, t2; @@ -510,17 +616,41 @@ trackfilter_split(void) } else { - float tr_interval; + new_track_flag = 1; - tr_interval = difftime(buff[j]->creation_time,buff[i]->creation_time); - new_track_flag = ( tr_interval > interval ); + if (distance > 0) + { + double rt1 = RAD(buff[i]->latitude); + double rn1 = RAD(buff[i]->longitude); + double rt2 = RAD(buff[j]->latitude); + double rn2 = RAD(buff[j]->longitude); + double curdist = gcdist( rt1, rn1, rt2, rn2 ); + curdist = radtomiles(curdist); + if ( curdist <= distance ) + new_track_flag = 0; #ifdef TRACKF_DBG - if (new_track_flag != 0) - printf(MYNAME ": split, %g > %g\n", tr_interval, interval ); + else + printf(MYNAME ": sdistance, %g > %g\n", curdist, distance ); #endif + } + + if (interval > 0) + { + float tr_interval = difftime(buff[j]->creation_time,buff[i]->creation_time); + if ( tr_interval <= interval ) + new_track_flag = 0; +#ifdef TRACKF_DBG + else + printf(MYNAME ": split, %g > %g\n", tr_interval, interval ); +#endif + } + } if (new_track_flag != 0) { +#ifdef TRACKF_DBG + printf(MYNAME ": splitting new track\n" ); +#endif curr = (route_head *) route_head_alloc(); trackfilter_split_init_rte_name(curr, buff[j]->creation_time); track_add_head(curr); @@ -528,8 +658,8 @@ trackfilter_split(void) if (curr != NULL) { wpt = waypt_dupe(buff[j]); - route_del_wpt(master, buff[j]); - route_add_wpt(curr, wpt); + track_del_wpt(master, buff[j]); + track_add_wpt(curr, wpt); buff[j] = wpt; } } @@ -564,6 +694,71 @@ trackfilter_move(void) } } +/******************************************************************************* +* options "fix", "course", "speed" +*******************************************************************************/ + +static void +trackfilter_synth(void) +{ + int i; + queue *elem, *tmp; + waypoint *wpt; + + double oldlat = -999; + double oldlon = -999; + time_t oldtime = 0; + int first = 1; + fix_type fix; + + fix = trackfilter_parse_fix(); + + for (i = 0; i < track_ct; i++) + { + route_head *track = track_list[i].track; + first = 1; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) + { + wpt = (waypoint *)elem; + if ( opt_fix ) { + wpt->fix = fix; + } + if ( first ) { + if ( opt_course ) { + wpt->course = 0; + } + if ( opt_speed ) { + wpt->speed = 0; + } + first = 0; + } + else { + if ( opt_course ) { + wpt->course = heading_true_degrees( RAD(oldlat), + RAD(oldlon),RAD(wpt->latitude), + RAD(wpt->longitude) ); + } + if ( opt_speed ) { + if ( oldtime != wpt->creation_time ) { + wpt->speed = radtometers(gcdist( + RAD(oldlat), RAD(oldlon), + RAD(wpt->latitude), + RAD(wpt->longitude))) / + labs(wpt->creation_time-oldtime); + } + else { + wpt->speed = unknown_speed; + } + } + } + oldlat = wpt->latitude; + oldlon = wpt->longitude; + oldtime = wpt->creation_time; + } + } +} + + /******************************************************************************* * option: "start" / "stop" *******************************************************************************/ @@ -610,7 +805,7 @@ trackfilter_range(void) /* returns number of track points left after filtering if (opt_stop != 0) stop = trackfilter_range_check(opt_stop); else - stop = (unsigned long)-1; + stop = 0x7FFFFFFF; dropped = 0; @@ -624,7 +819,7 @@ trackfilter_range(void) /* returns number of track points left after filtering if ((wpt->creation_time < start) || (wpt->creation_time > stop)) { - route_del_wpt(track, wpt); + track_del_wpt(track, wpt); dropped++; } } @@ -649,7 +844,7 @@ trackfilter_range(void) /* returns number of track points left after filtering static void trackfilter_init(const char *args) { - + int count = track_count(); track_ct = 0; @@ -661,7 +856,7 @@ trackfilter_init(const char *args) /* check all tracks for time and order (except merging) */ - track_disp_all(trackfilter_fill_track_list_cb, trackfilter_noop_t, trackfilter_noop_w); + track_disp_all(trackfilter_fill_track_list_cb, NULL, NULL); qsort(track_list, track_ct, sizeof(*track_list), trackfilter_init_qsort_cb); } } @@ -691,12 +886,25 @@ trackfilter_process(void) opts = trackfilter_opt_count(); if (opts == 0) opts = -1; /* flag for do "pack" by default */ - + + if (opt_name != NULL) + { + if (--opts == 0) return; + } + if (opt_move != NULL) /* Correct timestamps before any other op */ { trackfilter_move(); if (--opts == 0) return; } + + if ( opt_speed || opt_course || opt_fix ) { + trackfilter_synth(); + if ( opt_speed ) opts--; + if ( opt_course ) opts--; + if ( opt_fix ) opts--; + if ( !opts ) return; + } if ((opt_stop != NULL) || (opt_start != NULL)) { @@ -710,6 +918,8 @@ trackfilter_process(void) trackfilter_deinit(); /* reinitialize */ trackfilter_init(NULL); + if (track_ct == 0) return; /* no more track(s), no more fun */ + } if (opt_title != NULL) @@ -741,7 +951,7 @@ trackfilter_process(void) return; } - if (opt_split != NULL) + if ((opt_split != NULL) || (opt_sdistance != NULL)) { if (track_ct > 1) fatal(MYNAME "-split: Cannot split more than one track, please pack (or merge) before!\n"); @@ -761,3 +971,4 @@ filter_vecs_t trackfilter_vecs = { }; /******************************************************************************************/ +#endif // FILTERS_ENABLED diff --git a/transform.c b/transform.c new file mode 100644 index 000000000..c52843c32 --- /dev/null +++ b/transform.c @@ -0,0 +1,194 @@ +/* + + Transformation filter for GPS data. + + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "filterdefs.h" + +#if FILTERS_ENABLED + +#include + +#define MYNAME "transform" + +static char current_target; +static route_head *current_trk; +static route_head *current_rte; + +static char *opt_routes, *opt_tracks, *opt_waypts, *opt_delete; + +static +arglist_t transform_args[] = { + {"wpt", &opt_waypts, "Transform track(s) or route(s) into waypoint(s) [R/T]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {"rte", &opt_routes, "Transform waypoint(s) or track(s) into route(s) [W/T]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {"trk", &opt_tracks, "Transform waypoint(s) or route(s) into tracks(s) [W/R]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX}, + {"del", &opt_delete, "Delete source data after transformation", "N", + ARGTYPE_BOOL, ARG_NOMINMAX}, + ARG_TERMINATOR +}; + +static void +transform_waypoints(void) +{ + queue *elem, *tmp; + route_head *rte; + + rte = route_head_alloc(); + switch(current_target) { + case 'R': route_add_head(rte); break; + case 'T': track_add_head(rte); break; + } + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) + { + waypoint *wpt = (waypoint *) elem; + + wpt = waypt_dupe(wpt); + switch(current_target) { + case 'R': route_add_wpt(rte, wpt); break; + case 'T': track_add_wpt(rte, wpt); break; + } + } +} + +static void +transform_rte_disp_hdr_cb(const route_head *rte) +{ + if (current_target == 'T') { + current_trk = route_head_alloc(); + track_add_head(current_trk); + if (rte->rte_name && *rte->rte_name) + xasprintf(¤t_trk->rte_desc, "Generated from route %s", rte->rte_name); + } +} + +static void +transform_trk_disp_hdr_cb(const route_head *trk) +{ + if (current_target == 'R') { + current_rte = route_head_alloc(); + route_add_head(current_rte); + if (trk->rte_name && *trk->rte_name) + xasprintf(¤t_rte->rte_desc, "Generated from track %s", trk->rte_name); + } +} + +static void +transform_any_disp_wpt_cb(const waypoint *wpt) +{ + waypoint *temp = waypt_dupe(wpt); + waypt_add(temp); +} + +static void +transform_routes(void) +{ + route_disp_all(transform_rte_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); +} + +static void +transform_tracks(void) +{ + track_disp_all(transform_trk_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); +} + +/******************************************************************************* +* %%% global callbacks called by gpsbabel main process %%% * +*******************************************************************************/ + +static void +transform_init(const char *args) +{ +} + +static void +transform_deinit(void) +{ +} + +static void +transform_process(void) +{ + int delete_after = (opt_delete && (*opt_delete == '1')) ? 1 : 0; + + if (opt_waypts != NULL) { + current_target = 'W'; + switch(toupper(*opt_waypts)) { + case 'R': + transform_routes(); + if (delete_after) route_flush_all_routes(); + break; + case 'T': + transform_tracks(); + if (delete_after) route_flush_all_tracks(); + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_waypts); + } + } + if (opt_routes != NULL) { + current_target = 'R'; + switch(toupper(*opt_routes)) { + case 'W': + transform_waypoints(); + if (delete_after) waypt_flush_all(); + break; + case 'T': + transform_tracks(); + if (delete_after) route_flush_all_tracks(); + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_routes); + } + } + if (opt_tracks != NULL) { + current_target = 'T'; + switch(toupper(*opt_tracks)) { + case 'W': + transform_waypoints(); + if (delete_after) waypt_flush_all(); + break; + case 'R': + transform_routes(); + if (delete_after) route_flush_all_routes(); + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_tracks); + } + } +} + +/*******************************************************************************/ + +filter_vecs_t transform_vecs = { + transform_init, + transform_process, + transform_deinit, + NULL, + transform_args +}; + +/*******************************************************************************/ + +#endif // FILTERS_ENABLED diff --git a/unicsv.c b/unicsv.c new file mode 100644 index 000000000..3bd2ea1b1 --- /dev/null +++ b/unicsv.c @@ -0,0 +1,227 @@ +/* + Universal CSV - support for csv files, divining field order from the header. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + +#include "defs.h" +#include "csv_util.h" +#include "jeeps/gpsmath.h" + +#define MYNAME "unicsv" + +static gbfile *file_in; + +/* This structure must contain only ints. Firstval must be first. + * This is block initialized. + */ +struct { + int firstval; + int latcol; + int loncol; + int namecol; + int desccol; + int notescol; + int altcol; + int urlcol; + int utmzcol; /* Zone */ + int utmncol; /* Northing */ + int utmecol; /* Easting */ +} unicsv_fieldpos; + +static double unicsv_altscale; +static char *unicsv_fieldsep; + +static +arglist_t unicsv_args[] = { + ARG_TERMINATOR +}; + +/* helpers */ + +#define UNICSV_IS(f) (0 == strcmp(s, f)) +#define UNICSV_CONTAINS(f) (0 != strstr(s, f)) + +static void +unicsv_fondle_header(char *ibuf) +{ + char *s; + unsigned int i; + int *ip = &unicsv_fieldpos.firstval; + + for (i = 0; i < sizeof(unicsv_fieldpos) / sizeof(int); i++, ip++) { + *ip = -1; + } + + /* Convert the entire header to lower case for convenience. + * If we see a tab in that header, we decree it to be tabsep. + */ + unicsv_fieldsep = ","; + for (s = ibuf; *s; s++) { + if (*s == '\t') { + unicsv_fieldsep = "\t"; + } + else if (*s == ';') { + unicsv_fieldsep = ";"; + } + else { + *s = tolower(*s); + } + } + + s = csv_lineparse(ibuf, unicsv_fieldsep, "", 0); + for (i=0; s; i++,s = csv_lineparse(NULL, unicsv_fieldsep, "", 0)) { + if (UNICSV_CONTAINS("lat")) { + unicsv_fieldpos.latcol = i; + } + else if (UNICSV_IS("lon") || UNICSV_CONTAINS("long")) { + unicsv_fieldpos.loncol = i; + } + else if (UNICSV_CONTAINS("desc")) { + unicsv_fieldpos.desccol = i; + } + else if (UNICSV_IS("name")) { + unicsv_fieldpos.namecol = i; + } + else if (UNICSV_CONTAINS("notes")) { + unicsv_fieldpos.notescol = i; + } + else if (UNICSV_CONTAINS("alt")) { + unicsv_fieldpos.altcol = i; + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_altscale = FEET_TO_METERS(1); + } + } + else if (UNICSV_CONTAINS("url")) { + unicsv_fieldpos.urlcol = i; + } + else if (UNICSV_CONTAINS("utm z")) { + unicsv_fieldpos.utmzcol = i; + } + else if (UNICSV_CONTAINS("utm n")) { + unicsv_fieldpos.utmncol = i; + } + else if (UNICSV_CONTAINS("utm e")) { + unicsv_fieldpos.utmecol = i; + } +/* todo: speed, course, hdop, sat, date, time, maybe a few others */ + } +} + +static void +unicsv_rd_init(const char *fname) +{ + char *c; + unicsv_altscale = 1.0; + + file_in = gbfopen(fname, "rb", MYNAME); + + if ((c = gbfgetstr(file_in))) + unicsv_fondle_header(c); + else + unicsv_fieldsep = NULL; +} + +static void +unicsv_rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +unicsv_parse_one_line(char *ibuf) +{ + char *s; + waypoint *wpt; + int i; + int utmz = -9999; + double utme = 0; + double utmn = 0; + + s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0); + if (s == NULL) return; + + wpt = waypt_new(); + + for (i=0; s; i++, s = csv_lineparse(NULL, unicsv_fieldsep, "\"", 0)) { + if (i == unicsv_fieldpos.latcol) { + human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); + } + else if (i == unicsv_fieldpos.loncol) { + human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); + } + else if (i == unicsv_fieldpos.namecol) { + wpt->shortname = xstrdup(s); + } + else if (i == unicsv_fieldpos.desccol) { + wpt->description = xstrdup(s); + } + else if (i == unicsv_fieldpos.notescol) { + wpt->notes = xstrdup(s); + } + else if (i == unicsv_fieldpos.urlcol) { + wpt->url = xstrdup(s); + } + else if (i == unicsv_fieldpos.altcol) { + wpt->altitude = atof(s) * unicsv_altscale; + } + else if (i == unicsv_fieldpos.utmzcol) { + utmz = atoi(s); + } + else if (i == unicsv_fieldpos.utmecol) { + utme = atof(s); + } + else if (i == unicsv_fieldpos.utmncol) { + utmn = atof(s); + } + } + if (utmz != -9999) { + GPS_Math_UTM_EN_To_WGS84(&wpt->latitude, &wpt->longitude, + utme, utmn, utmz, 'N'); + } + waypt_add(wpt); +} + +static void +unicsv_rd(void) +{ + char *buff; + + if (unicsv_fieldsep == NULL) return; + + while ((buff = gbfgetstr(file_in))) { + buff = lrtrim(buff); + if (*buff) + unicsv_parse_one_line(buff); + } +} + +/* --------------------------------------------------------------------------- */ + +ff_vecs_t unicsv_vecs = { + ff_type_file, + { ff_cap_read, 0, 0}, + unicsv_rd_init, + NULL, + unicsv_rd_deinit, + NULL, + unicsv_rd, + NULL, + NULL, + unicsv_args, + CET_CHARSET_ASCII, 0 /* can be changed with -c ... */ +}; diff --git a/units.c b/units.c new file mode 100644 index 000000000..d3a85bfed --- /dev/null +++ b/units.c @@ -0,0 +1,94 @@ +/* + Display scaled distances in 'local' units. + + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +static int units = units_statute; + +int +fmt_setunits(fmt_units u) +{ + switch (u) { + case units_statute: + case units_metric: + units = u; + return 0; + default: + return 1; + } +} + +double +fmt_distance(const double distance_meters, char **tag) +{ + double d; + + switch (units) { + case units_statute: + d = METERS_TO_FEET(distance_meters); + if (d < 5280) { + *tag = "ft"; + } else { + d = METERS_TO_MILES(distance_meters); + *tag = "mi"; + } + break; + case units_metric: + d = distance_meters; + if (d < 1000) { + *tag = "meters"; + } else { + d = d / (double) 1000.0; + *tag = "km"; + } + break; + + default: + fatal("not done yet"); + break; + } + + return d; +} + +double +fmt_speed(const double distance_meters_sec, char **tag) +{ + double d; + + switch (units) { + case units_statute: + d = METERS_TO_MILES(distance_meters_sec) * SECONDS_PER_HOUR ; + *tag = "mph"; + break; + case units_metric: + d = distance_meters_sec * SECONDS_PER_HOUR; + *tag = "meters/hour"; + if (d > 1000.0) { + d /= 1000.0; + *tag = "km/hour"; + } + break; + default: fatal("not done yet"); + + } + return d; +} diff --git a/util.c b/util.c index 654eeefbc..9fa021459 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* Misc utilities. - Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002-2005 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,9 +24,14 @@ #include #include #include +#include +#include -static int i_am_little_endian = -1; -static int doswap(void); +#if defined WORDS_BIGENDIAN +# define i_am_little_endian 0 +#else +# define i_am_little_endian 1 +#endif #ifdef DEBUG_MEM #define DEBUG_FILENAME "/tmp/gpsbabel.debug" @@ -74,7 +79,7 @@ xmalloc(size_t size) obj, size, file, line ); #endif if (!obj) { - fatal("gpsbabel: Unable to allocate %d bytes of memory.\n", size); + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) size); } return obj; @@ -94,7 +99,7 @@ xcalloc(size_t nmemb, size_t size) #endif if (!obj) { - fatal("gpsbabel: Unable to allocate %d bytes of memory.\n", size); + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) size); } return obj; @@ -128,7 +133,7 @@ xstrdup(const char *s) #endif if (!o) { - fatal("gpsbabel: Unable to allocate %d bytes of memory.\n", strlen(s)); + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) strlen(s)); } return o; @@ -144,14 +149,15 @@ XSTRNDUP(const char *str, size_t sz, DEBUG_PARAMS ) xstrndup(const char *str, size_t sz) #endif { - size_t newlen; + size_t newlen = 0; + char *cin = (char *)str; char *newstr; - newlen = strlen(str); - if (newlen > sz) { - newlen = sz; + while ((newlen < sz) && (*cin != '\0')) { + newlen++; + cin++; } - + newstr = (char *) xmalloc(newlen + 1); memcpy(newstr, str, newlen); newstr[newlen] = 0; @@ -170,17 +176,18 @@ XSTRNDUPT(const char *str, size_t sz, DEBUG_PARAMS ) xstrndupt(const char *str, size_t sz) #endif { - size_t newlen; + size_t newlen = 0; + char *cin = (char *)str; char *newstr; - newlen = strlen(str); - if (newlen > sz) { - newlen = sz; + while ((newlen < sz) && (*cin != '\0')) { + newlen++; + cin++; } - + newstr = (char *) xmalloc(newlen + 1); - memcpy(newstr, str, newlen); - newstr[newlen] = '\0'; + memcpy(newstr, str, newlen); + newstr[newlen] = 0; rtrim(newstr); return newstr; @@ -200,7 +207,7 @@ xrealloc(void *p, size_t s) #endif if (!o) { - fatal("gpsbabel: Unable to realloc %d bytes of memory.\n", s); + fatal("gpsbabel: Unable to realloc %ld bytes of memory.\n", (unsigned long) s); } return o; @@ -221,6 +228,9 @@ xstrappend(char *src, const char *newd) if (!src) { return xxstrdup(newd, file, line); } + if (!newd) { + return xxstrdup(src, file, line); + } newsz = strlen(src) + strlen(newd) + 1; src = xxrealloc(src, newsz, file, line); @@ -276,6 +286,95 @@ xfputs(const char *errtxt, const char *s, FILE *stream) } } +/* + * Allocate a string using a format list with optional arguments + */ + +int +xvasprintf(char **strp, const char *fmt, va_list args) +{ + /* From http://perfec.to/vsnprintf/pasprintf.c */ +/* size of first buffer malloc; start small to exercise grow routines */ +#define FIRSTSIZE 64 + char *buf = NULL; + int bufsize; + char *newbuf; + size_t nextsize = 0; + int outsize; + + bufsize = 0; + for (;;) { + if (bufsize == 0) { + if ((buf = xmalloc(FIRSTSIZE)) == NULL) { + *strp = NULL; + return -1; + } + bufsize = 1; + } else if ((newbuf = xrealloc(buf, nextsize)) != NULL) { + buf = newbuf; + bufsize = nextsize; + } else { + xfree(buf); + *strp = NULL; + return -1; + } + + outsize = vsnprintf(buf, bufsize, fmt, args); + + if (outsize == -1) { + /* Clear indication that output was truncated, but no + * clear indication of how big buffer needs to be, so + * simply double existing buffer size for next time. + */ + nextsize = bufsize * 2; + + } else if (outsize == bufsize) { + /* Output was truncated (since at least the \0 could + * not fit), but no indication of how big the buffer + * needs to be, so just double existing buffer size + * for next time. + */ + nextsize = bufsize * 2; + + } else if (outsize > bufsize) { + /* Output was truncated, but we were told exactly how + * big the buffer needs to be next time. Add two chars + * to the returned size. One for the \0, and one to + * prevent ambiguity in the next case below. + */ + nextsize = outsize + 2; + + } else if (outsize == bufsize - 1) { + /* This is ambiguous. May mean that the output string + * exactly fits, but on some systems the output string + * may have been trucated. We can't tell. + * Just double the buffer size for next time. + */ + nextsize = bufsize * 2; + + } else { + /* Output was not truncated */ + break; + } + } + *strp = buf; + return 0; +} + +int +xasprintf(char **strp, const char *fmt, ...) +{ + va_list args; + int rval; + + va_start(args, fmt); + rval = xvasprintf(strp, fmt, args); + va_end(args); + + return rval; + +} + /* * Duplicate a pascal string into a normal C string. */ @@ -311,6 +410,23 @@ rtrim(char *s) } } +/* + * Like trim, but trims whitespace from both beginning and end. + */ +char * +lrtrim(char *buff) +{ + char *c; + + c = buff + strlen(buff); + while ((c >= buff) && ((unsigned char)*c <= ' ')) *c-- = '\0'; + + c = buff; + while ((*c != '\0') && ((unsigned char)*c <= ' ')) c++; + + return c; +} + /* * Like strcmp, but case insensitive. Like Berkeley's strcasecmp. */ @@ -340,6 +456,126 @@ case_ignore_strncmp(const char *s1, const char *s2, int n) return rv; } +/* + * compare str with match + * match may contain wildcards "*" and "?" + * + * examples: + * str_match("ABCDE", "*BC*") -> 1 + * str_match("ABCDE", "A*C*E") -> 1 + * str_match("?ABCDE", "\\?A*") -> 1 + * str_match("", "*A") -> 0 + */ + +int +str_match(const char *str, const char *match) +{ + char *m, *s; + + s = (char *)str; + m = (char *)match; + + while (*m || *s) + { + switch(*m) + { + + case '\0': + /* there is something left in s, FAIL */ + return 0; + + case '*': + /* skip all wildcards */ + while ((*m == '*') || (*m == '?')) m++; + if (*m == '\0') return 1; + + if (*m == '\\') /* ? escaped ? */ + { + m++; + if (*m == '\0') return 0; + } + + do + { + char *mx, *sx; + + while (*s && (*s != *m)) s++; + if (*s == '\0') return 0; + + sx = s + 1; + mx = m + 1; + + while (*sx) + { + if (*mx == '\\') /* ? escaped ? */ + { + mx++; + if (*mx == '\0') return 0; + + } + if (*sx == *mx) + { + sx++; + mx++; + } + else + break; + } + if (*mx == '\0') /* end of match */ + { + if (*sx == '\0') return 1; + s++; + } + else if ((*mx == '?') || (*mx == '*')) + { + s = sx; + m = mx; + break; + } + else + s++; + } while (*s); + break; + + case '?': + if (*s == '\0') return 0; /* no character left */ + m++; + s++; + break; + + case '\\': + m++; + if (*m == '\0') return 0; /* incomplete escape sequence */ + /* pass-through next character */ + + default: + if (*m != *s) return 0; + m++; + s++; + } + } + return ((*s == '\0') && (*m == '\0')); +} + +/* + * as str_match, but case insensitive + */ + +int +case_ignore_str_match(const char *str, const char *match) +{ + char *s1, *s2; + int res; + + s1 = strupper(xstrdup(str)); + s2 = strupper(xstrdup(match)); + res = str_match(s1, s2); + xfree(s1); + xfree(s2); + + return res; +} + void printposn(const double c, int is_lat) { @@ -353,43 +589,39 @@ printposn(const double c, int is_lat) } void -fatal(const char *fmt, ...) +is_fatal(const int condition, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} + va_list args; + char buff[128]; -void -warning(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + if (condition == 0) return; + + va_start(args, fmt); + vsnprintf(buff, sizeof(buff), fmt, args); + va_end(args); + + fatal("%s\n", buff); } /* * Read 4 bytes in big-endian. Return as "int" in native endianness. */ signed int -be_read32(void *p) +be_read32(const void *p) { unsigned char *i = (unsigned char *) p; return i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3]; } signed int -be_read16(void *p) +be_read16(const void *p) { unsigned char *i = (unsigned char *) p; return i[0] << 8 | i[1]; } void -be_write16(void *addr, unsigned value) +be_write16(void *addr, const unsigned value) { unsigned char *p = addr; p[0] = value >> 8; @@ -398,7 +630,7 @@ be_write16(void *addr, unsigned value) } void -be_write32(void *pp, unsigned i) +be_write32(void *pp, const unsigned i) { char *p = (char *)pp; @@ -409,16 +641,16 @@ be_write32(void *pp, unsigned i) } signed int -le_read16(void *addr) +le_read16(const void *addr) { - unsigned char *p = addr; + const unsigned char *p = addr; return p[0] | (p[1] << 8); } signed int -le_read32(void *addr) +le_read32(const void *addr) { - unsigned char *p = addr; + const unsigned char *p = addr; return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); } @@ -432,8 +664,6 @@ le_read64(void *dest, const void *src) char *cdest = dest; const char *csrc = src; - doswap(); /* make sure i_am_little_endian is initialized */ - if (i_am_little_endian) { memcpy(dest, src, 8); } else { @@ -445,7 +675,7 @@ le_read64(void *dest, const void *src) } void -le_write16(void *addr, unsigned value) +le_write16(void *addr, const unsigned value) { unsigned char *p = addr; p[0] = value; @@ -454,7 +684,7 @@ le_write16(void *addr, unsigned value) } void -le_write32(void *addr, unsigned value) +le_write32(void *addr, const unsigned value) { unsigned char *p = addr; p[0] = value; @@ -539,6 +769,26 @@ mkgmtime(struct tm *t) return(result); } +/* + * mklocaltime: same as mktime, but try to recover the "Summer time flag", + * which is evaluated by mktime + */ +time_t +mklocaltime(struct tm *t) +{ + time_t result; + struct tm check = *t; + + check.tm_isdst = 0; + result = mktime(&check); + check = *localtime(&result); + if (check.tm_isdst == 1) { /* DST is in effect */ + check = *t; + check.tm_isdst = 1; + result = mktime(&check); + } + return result; +} /* * A wrapper for time(2) that allows us to "freeze" time for testing. @@ -611,56 +861,65 @@ get_cache_icon(const waypoint *waypointp) return NULL; } -static int doswap() -{ - if (i_am_little_endian < 0) - { - /* On Intel, Vax and MIPs little endian, -1.0 maps to the bytes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f and on Motorola, - SPARC, ARM, and PowerPC, it maps to - 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00. - */ - double d = 1.0; - char c[8]; - memcpy(c, &d, 8); - i_am_little_endian = (c[0] == 0); - } - return i_am_little_endian; -} - double -pdb_read_double(void* ptr) +endian_read_double(void* ptr, int read_le) { double ret; char r[8]; + void *p; int i; - doswap(); /* make sure i_am_little_endian is initialized */ - for (i = 0; i < 8; i++) - { - int j = (i_am_little_endian)?(7-i):i; - r[i] = ((char*)ptr)[j]; + + if ( i_am_little_endian == read_le ) { + p = ptr; } - memcpy(&ret, r, 8); + else { + for (i = 0; i < 8; i++) + { + r[i] = ((char*)ptr)[7-i]; + } + p = r; + } + + memcpy(&ret, p, 8); return ret; } void -pdb_write_double(void* ptr, double d) +endian_write_double(void* ptr, double d, int write_le) { - char r[8]; + char *r = (char *)(void *)&d; int i; char *optr = ptr; - memcpy(r, &d, 8); - doswap(); /* make sure i_am_little_endian is initialized */ - for (i = 0; i < 8; i++) - { - int j = (i_am_little_endian)?(7-i):i; - *optr++ = r[j]; + if ( i_am_little_endian == write_le ) { + memcpy( ptr, &d, 8); + } + else { + for (i = 0; i < 8; i++) + { + *optr++ = r[7-i]; + } } - return; } +double +pdb_read_double( void *ptr ) {return endian_read_double(ptr, 0);} + +double +le_read_double( void *ptr ) {return endian_read_double(ptr,1);} + +double +be_read_double( void *ptr ) {return endian_read_double(ptr,0);} + +void +pdb_write_double( void *ptr, double d ) {endian_write_double(ptr,d,0);} + +void +le_write_double( void *ptr, double d ) {endian_write_double(ptr,d,1);} + +void +be_write_double( void *ptr, double d ) {endian_write_double(ptr,d,0);} + /* Magellan and PCX formats use this DDMM.mm format */ double ddmm2degrees(double pcx_val) { double minutes; @@ -727,6 +986,49 @@ gstrsub(const char *s, const char *search, const char *replace) return o; } +/* + * Like strstr, but starts from back of string. + */ +char * +xstrrstr(const char *s1, const char *s2) +{ + char *r = NULL, *next = NULL; + + while (next = strstr(s1, s2), NULL != next) { + r = next; + s1 = next + 1; + } + return r; +} + +/* + * + */ +char * +strupper(char *src) +{ + char *c; + + for (c = src; *c; c++) { + *c = toupper(*c); + } + return src; +} + +/* + * + */ +char * +strlower(char *src) +{ + char *c; + + for (c = src; *c; c++) { + *c = tolower(*c); + } + return src; +} + char * rot13( const char *s ) { @@ -749,255 +1051,211 @@ rot13( const char *s ) return result; } -void utf8_to_int( const char *cp, int *bytes, int *value ) -{ - if ( (*cp & 0xe0) == 0xc0 ) { - if ( (*(cp+1) & 0xc0) != 0x80 ) goto dodefault; - *bytes = 2; - *value = ((*cp & 0x1f) << 6) | - (*(cp+1) & 0x3f); - } - else if ( (*cp & 0xf0) == 0xe0 ) { - if ( (*(cp+1) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+2) & 0xc0) != 0x80 ) goto dodefault; - *bytes = 3; - *value = ((*cp & 0x0f) << 12) | - ((*(cp+1) & 0x3f) << 6) | - (*(cp+2) & 0x3f); - } - else if ( (*cp & 0xf8) == 0xf0 ) { - if ( (*(cp+1) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+2) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+3) & 0xc0) != 0x80 ) goto dodefault; - *bytes = 4; - *value = ((*cp & 0x07) << 18) | - ((*(cp+1) & 0x3f) << 12) | - ((*(cp+2) & 0x3f) << 6) | - (*(cp+3) & 0x3f); - } - else if ( (*cp & 0xfc) == 0xf8 ) { - if ( (*(cp+1) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+2) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+3) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+4) & 0xc0) != 0x80 ) goto dodefault; - *bytes = 5; - *value = ((*cp & 0x03) << 24) | - ((*(cp+1) & 0x3f) << 18) | - ((*(cp+2) & 0x3f) << 12) | - ((*(cp+3) & 0x3f) << 6) | - (*(cp+4) & 0x3f); - } - else if ( (*cp & 0xfe) == 0xfc ) { - if ( (*(cp+1) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+2) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+3) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+4) & 0xc0) != 0x80 ) goto dodefault; - if ( (*(cp+5) & 0xc0) != 0x80 ) goto dodefault; - *bytes = 6; - *value = ((*cp & 0x01) << 30) | - ((*(cp+1) & 0x3f) << 24) | - ((*(cp+2) & 0x3f) << 18) | - ((*(cp+3) & 0x3f) << 12) | - ((*(cp+4) & 0x3f) << 6) | - (*(cp+5) & 0x3f); - } - else { -dodefault: - *bytes = 1; - *value = (unsigned char)*cp; - } -} - -char * str_utf8_to_cp1252( const char * str ) +/* + * Convert a human readable date format (i.e. "YYYY/MM/DD") into + * a format usable for strftime and others + */ + +char * +convert_human_date_format(const char *human_datef) { - char *result = xstrdup( str ); - char *cur = result; + char *result, *cin, *cout; + char prev; + int ylen; + + result = xcalloc((2*strlen(human_datef)) + 1, 1); + cout = result; + prev = '\0'; + ylen = 0; - while ( cur && *cur ) { - if ( *cur & 0x80 ) { - int bytes; - int value; - utf8_to_int( cur, &bytes, &value ); - if ( value > 0xff ) { - switch (value) { - case 0x20AC: value = 0x80; break; - case 0x201A: value = 0x82; break; - case 0x0192: value = 0x83; break; - case 0x201E: value = 0x84; break; - case 0x2026: value = 0x85; break; - case 0x2020: value = 0x86; break; - case 0x2021: value = 0x87; break; - case 0x02C6: value = 0x88; break; - case 0x2030: value = 0x89; break; - case 0x0160: value = 0x8A; break; - case 0x2039: value = 0x8B; break; - case 0x0152: value = 0x8C; break; - case 0x017D: value = 0x8E; break; - case 0x2018: value = 0x91; break; - case 0x2019: value = 0x92; break; - case 0x201C: value = 0x93; break; - case 0x201D: value = 0x94; break; - case 0x2022: value = 0x95; break; - case 0x2013: value = 0x96; break; - case 0x2014: value = 0x97; break; - case 0x02DC: value = 0x98; break; - case 0x2122: value = 0x99; break; - case 0x0161: value = 0x9A; break; - case 0x203A: value = 0x9B; break; - case 0x0153: value = 0x9C; break; - case 0x017E: value = 0x9E; break; - case 0x0178: value = 0x9F; break; - /* default is the generic "currency */ - /* sign" because question marks */ - /* just look stupid. */ - default: value = 0xA4; break; + for (cin = (char *)human_datef; *cin; cin++) + { + char okay = 1; + + if (toupper(*cin) != 'Y') ylen = 0; + if (isalpha(*cin)) + { + switch(*cin) + { + case 'y': case 'Y': + if (prev != 'Y') + { + strcat(cout, "%y"); + cout += 2; + prev = 'Y'; + } + ylen++; + if (ylen > 2) *(cout-1) = 'Y'; + break; + case 'm': case 'M': + if (prev != 'M') + { + strcat(cout, "%m"); + cout += 2; + prev = 'M'; + } + break; + case 'd': case 'D': + if (prev != 'D') + { + strcat(cout, "%d"); + cout += 2; + prev = 'D'; } + break; + default: + okay = 0; } - *cur = (char)value; - memmove(cur+1, cur+bytes, strlen(cur+bytes) + 1); } - cur++; + else if (ispunct(*cin)) + { + *cout++ = *cin; + prev = '\0'; + } + else okay = 0; + + is_fatal(okay == 0, "Invalid character \"%c\" in date format!", *cin); } return result; } -#if 0 /* - * Convert to ISO 8859-1 (LATIN-1). The result is never longer than - * the source. + * Convert a human readable time format (i.e. "HH:mm:ss") into + * a format usable for strftime and others */ -char * -str_utf8_to_8859_1( const char * str ) -{ - char *result = xstrdup( str ); - char *cur = result; - unsigned char c; - - while (c = *str++) { - if (c < 0x80) { - *cur++ = c; - continue; - } - if ((c & 0xFE) == 0xC2) { - *cur++ = ((c & 0x03) << 6) | (*str++ & 0x3f); - } - } - return result; -} -#endif - -char * str_utf8_to_ascii( const char * str ) +char * +convert_human_time_format(const char *human_timef) { - char *result; - char *cur; - - if (!str) return NULL; - - result = xstrdup( str ); - cur = result; + char *result, *cin, *cout; + char prev; - while ( cur && *cur ) { - if ( *cur & 0x80 ) { - int bytes; - int value; - char *strvalue = NULL; - utf8_to_int( cur, &bytes, &value ); - switch (value) { - case 0x2026: strvalue = "..."; break; - case 0x201c: value = '\"'; break; - case 0x201d: value = '\"'; break; - case 0xb4: - case 0x2018: value = '`'; break; - case 0x2019: value = '\''; break; - - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: value = 'o'; break; - - case 0xe0: - case 0xe1: - case 0xe2: - case 0xe3: - case 0xe4: - case 0xe5: value = 'a'; break; - - case 0xe8: - case 0xe9: - case 0xea: - case 0xeb: value = 'e'; break; - - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: value = 'A'; break; - - case 0xf8: value = '0'; break; - default: value='?'; break;; - } - if (strvalue) { - memcpy(cur, strvalue, bytes); - cur += bytes - 1; - } else { - *cur = (char)value; - memmove(cur+1, cur+bytes, strlen(cur+bytes)); + result = xcalloc((2*strlen(human_timef)) + 1, 1); + cout = result; + prev = '\0'; + + for (cin = (char *)human_timef; *cin; cin++) + { + int okay = 1; + + if (isalpha(*cin)) + { + switch(*cin) + { + case 'S': case 's': + if (prev != 'S') { + strcat(cout, "%S"); + cout += 2; + prev = 'S'; + } + break; + + case 'M': case 'm': + if (prev != 'M') { + strcat(cout, "%M"); + cout += 2; + prev = 'M'; + } + break; + + case 'h': /* 12-hour-clock */ + if (prev != 'H') { + strcat(cout, "%l"); /* 1 .. 12 */ + cout += 2; + prev = 'H'; + } + else *(cout-1) = 'I'; /* 01 .. 12 */ + break; + + case 'H': /* 24-hour-clock */ + if (prev != 'H') { + strcat(cout, "%k"); + cout += 2; + prev = 'H'; + } + else *(cout-1) = 'H'; + break; + + case 'x': + if (prev != 'X') { + strcat(cout, "%P"); + cout += 2; + prev = 'X'; + } + else *(cout-1) = 'P'; + break; + + case 'X': + if (prev != 'X') { + strcat(cout, "%p"); + cout += 2; + prev = 'X'; + } + else *(cout-1) = 'p'; + break; + + default: + okay = 0; } } - cur++; + else if (ispunct(*cin) || isspace(*cin)) + { + *cout++ = *cin; + prev = '\0'; + } + else okay = 0; + + is_fatal(okay == 0, "Invalid character \"%c\" in time format!", *cin); } return result; } -/* - * str_iso8859_1_to_utf8 - * - * converts the single byte charset ISO8859-1 (latin1) to UTF-8 - */ +/* + * Return a decimal degree pair as + * DD.DDDDD DD MM.MMM or DD MM SS.S + * fmt = ['d', 'm', 's'] + * html = 1 for html output otherwise text + */ char * -str_iso8859_1_to_utf8(const char *s) +pretty_deg_format(double lat, double lon, char fmt, int html) { - int len; - char *res; - unsigned char c; - char *src, *dst; - - if (s == NULL) return NULL; - - len = 0; - src = (char *)s; - while ('\0' != (c = *src++)) - { - len++; - if (c & 0x80) len++; + double latmin, lonmin, latsec, lonsec; + int latint, lonint; + char latsig, lonsig; + char *result; + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + if (fmt == 'd') { /* ddd */ + xasprintf ( &result, "%c%6.5f%s %c%6.5f%s", + latsig, fabs(lat), html?"°":"", + lonsig, fabs(lon), html?"°":"" ); } - - src = (char *)s; - dst = res = (void *) xmalloc(len + 1); - while ('\0' != (c = *src++)) - { - if (c & 0x80) - { - *dst++ = (0xc0 | (c >> 6)); - *dst++ = (c & 0xbf); - } - else - { - *dst++ = c; - } + else if (fmt == 's') { /* dms */ + xasprintf ( &result, "%c%d%s%02d'%04.1f\" %c%d%s%02d'%04.1f\"", + latsig, latint, html?"°":" ", (int)latmin, latsec, + lonsig, lonint, html?"°":" ", (int)lonmin, lonsec); } - *dst = '\0'; - return res; + else { /* default dmm */ + xasprintf ( &result, "%c%d%s%06.3f %c%d%s%06.3f", + latsig, latint, html?"°":" ", latmin, + lonsig, lonint, html?"°":" ", lonmin); + } + return result; } + + /* * Get rid of potentially nasty HTML that would influence another record * that includes; - * - to stop backgrounds from being loaded + * - to stop backgrounds/background colours from being loaded * and - stop processing altogether * - stop overriding styles for everything */ @@ -1008,38 +1266,43 @@ strip_nastyhtml(const char * in) char *lcstr, *lcp; sp = returnstr = xstrdup(in); - lcp = lcstr = xstrdup(in); + lcp = lcstr = strlower(xstrdup(in)); - while (*lcp) { - *lcp = tolower(*lcp); - lcp++; + while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + sp++; *sp++ = '!'; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; + *lcp = '*'; /* so we wont find it again */ } - while (lcp = strstr(lcstr, " */ sp = returnstr + (lcp - lcstr) ; - sp++; *sp++ = '-'; *sp++ = '-'; *sp++ = '-'; *sp++ = '-'; + sp++; *sp++ = '!'; *sp++ = '-'; *sp++ = '-'; + while ( (*sp) && (*sp != '>') ) { + sp++; + } + *--sp = '-'; *--sp = '-'; *lcp = '*'; /* so we wont find it again */ } - while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = '-'; *sp++ = '-'; *lcp = '*'; /* so we wont find it again */ } - while (lcp = strstr(lcstr, "utfstring; char tag[8]; - short int taglen; + unsigned short int taglen = 0; if (!in->is_html) return xstrdup(in->utfstring); @@ -1078,8 +1341,15 @@ strip_html(const utf_string *in) } if (! tag[0]) { - if (*instr != '\n') + if (*instr == '\n') { + *out++ = ' '; + do { + instr++; + } while (isspace(*instr)); + continue; + } else { *out++ = *instr; + } } else { if (taglen < (sizeof(tag)-1)) { @@ -1117,7 +1387,7 @@ strip_html(const utf_string *in) tag[0] = 0; } - *instr++; + instr++; } *out++ = 0; return (outstring); @@ -1148,7 +1418,6 @@ entitize(const char * str, int is_html) const char * cp; char * p, * tmp, * xstr; - char tmpsub[20]; int bytes = 0; int value = 0; ep = stdentities; @@ -1167,15 +1436,17 @@ entitize(const char * str, int is_html) /* figure the same for other than standard entities (i.e. anything * that isn't in the range U+0000 to U+007F */ + +#if 0 for ( cp = str; *cp; cp++ ) { if ( *cp & 0x80 ) { - - utf8_to_int( cp, &bytes, &value ); + cet_utf8_to_ucs4( cp, &bytes, &value ); cp += bytes-1; elen += sprintf( tmpsub, "&#x%x;", value ) - bytes; nsecount++; } } +#endif /* enough space for the whole string plus entity replacements, if any */ tmp = xcalloc((strlen(str) + elen + 1), 1); @@ -1210,7 +1481,7 @@ entitize(const char * str, int is_html) p = tmp; while (*p) { if ( *p & 0x80 ) { - utf8_to_int( p, &bytes, &value ); + cet_utf8_to_ucs4( p, &bytes, &value ); if ( p[bytes] ) { xstr = xstrdup( p + bytes ); } diff --git a/util_crc.c b/util_crc.c index 390e66a77..cba43adcb 100644 --- a/util_crc.c +++ b/util_crc.c @@ -79,3 +79,18 @@ get_crc32(const void * data, int datalen) return (crc ^ 0xFFFFFFFF); } + +/* + * As above, but on null-terminated string. + */ +unsigned long +get_crc32_s(const void *data) +{ + unsigned long crc = 0xFFFFFFFF; + const unsigned char* cp = (unsigned char *)data; + + for (;*cp;cp++) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + } + return (crc ^ 0xFFFFFFFF); +} diff --git a/uuid.c b/uuid.c index f7e568ca3..cba1d65ff 100644 --- a/uuid.c +++ b/uuid.c @@ -21,7 +21,7 @@ #include void -uuid_generate(uuid_t uu) +gb_uuid_generate(uuid_t uu) { unsigned char *cp; int i; diff --git a/uuid.h b/uuid.h index fb8dc02fc..161b89e91 100644 --- a/uuid.h +++ b/uuid.h @@ -19,4 +19,4 @@ typedef unsigned char uuid_t[16]; -void uuid_generate(uuid_t uu); +void gb_uuid_generate(uuid_t uu); diff --git a/vcf.c b/vcf.c index aa6911acc..5ba4608ef 100644 --- a/vcf.c +++ b/vcf.c @@ -24,17 +24,17 @@ #include static FILE *file_out; -static void *mkshort_handle; +static short_handle mkshort_handle; -static char *encrypt = NULL; +static char *vcf_encrypt = NULL; #define MYNAME "VCF" static arglist_t vcf_args[] = { - { "encrypt", &encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + { "encrypt", &vcf_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; static void @@ -48,7 +48,7 @@ static void wr_deinit(void) { fclose(file_out); - mkshort_del_handle(mkshort_handle); + mkshort_del_handle(&mkshort_handle); } /* @@ -107,7 +107,7 @@ vcf_disp(const waypoint *wpt) fprintf(file_out, "\\n"); vcf_print_utf(&wpt->gc_data.desc_long); fprintf(file_out, "\\n\\nHINT:\\n"); - if (encrypt) { + if (vcf_encrypt) { char *s = rot13(wpt->gc_data.hint); vcf_print(s); xfree(s); @@ -136,5 +136,6 @@ ff_vecs_t vcf_vecs = { NULL, data_write, NULL, - vcf_args + vcf_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/vecs.c b/vecs.c index a1656ee71..7d3befe36 100644 --- a/vecs.c +++ b/vecs.c @@ -1,7 +1,7 @@ /* Describe vectors containing file operations. - Copyright (C) 2002, 2004, 2005 Robert Lipe, robertlipe@usa.net + Copyright (C) 2002, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,73 +22,99 @@ #include #include "defs.h" #include "csv_util.h" +#include "inifile.h" + +#define MYNAME "vecs.c" typedef struct { ff_vecs_t *vec; const char *name; const char *desc; const char *extension; + const char *parent; } vecs_t; +extern ff_vecs_t an1_vecs; +extern ff_vecs_t axim_gpb_vecs; +extern ff_vecs_t bcr_vecs; +extern ff_vecs_t brauniger_iq_vecs; +extern ff_vecs_t cetus_vecs; +extern ff_vecs_t coastexp_vecs; +extern ff_vecs_t compegps_vecs; +extern ff_vecs_t copilot_vecs; +extern ff_vecs_t coto_vecs; +extern ff_vecs_t cst_vecs; +extern ff_vecs_t easygps_vecs; +extern ff_vecs_t garmin_vecs; +extern ff_vecs_t garmin_txt_vecs; +extern ff_vecs_t gcdb_vecs; +extern ff_vecs_t gdb_vecs; +extern ff_vecs_t geoniche_vecs; extern ff_vecs_t geo_vecs; +extern ff_vecs_t glogbook_vecs; +extern ff_vecs_t google_vecs; +extern ff_vecs_t gpilots_vecs; +extern ff_vecs_t gpl_vecs; +extern ff_vecs_t gpssim_vecs; +extern ff_vecs_t gpspilot_vecs; +extern ff_vecs_t gpsutil_vecs; extern ff_vecs_t gpx_vecs; -extern ff_vecs_t mag_svecs; +extern ff_vecs_t gtm_vecs; +extern ff_vecs_t hiketech_vecs; +extern ff_vecs_t holux_vecs; +extern ff_vecs_t HsaEndeavourNavigator_vecs; +extern ff_vecs_t html_vecs; +extern ff_vecs_t igc_vecs; +extern ff_vecs_t ignr_vecs; +extern ff_vecs_t kml_vecs; +extern ff_vecs_t lowranceusr_vecs; extern ff_vecs_t mag_fvecs; +extern ff_vecs_t maggeo_vecs; +extern ff_vecs_t magnav_vec; +extern ff_vecs_t magpdb_vecs; +extern ff_vecs_t mag_svecs; extern ff_vecs_t magX_fvecs; extern ff_vecs_t mapsend_vecs; extern ff_vecs_t mps_vecs; -extern ff_vecs_t gpsutil_vecs; -extern ff_vecs_t tiger_vecs; +extern ff_vecs_t msroute_vecs; +extern ff_vecs_t navicache_vecs; +extern ff_vecs_t netstumbler_vecs; +extern ff_vecs_t nmea_vecs; +extern ff_vecs_t nmn4_vecs; +extern ff_vecs_t overlay_vecs; +extern ff_vecs_t ozi_vecs; +extern ff_vecs_t palmdoc_vecs; extern ff_vecs_t pcx_vecs; -extern ff_vecs_t lowranceusr_vecs; -extern ff_vecs_t cetus_vecs; -extern ff_vecs_t gpspilot_vecs; -extern ff_vecs_t copilot_vecs; +extern ff_vecs_t ppdb_vecs; +extern ff_vecs_t psit_vecs; /* MRCB */ extern ff_vecs_t psp_vecs; -extern ff_vecs_t garmin_vecs; -extern ff_vecs_t holux_vecs; -extern ff_vecs_t xcsv_vecs; -extern ff_vecs_t tpg_vecs; -extern ff_vecs_t magnav_vec; -extern ff_vecs_t tmpro_vecs; -extern ff_vecs_t gcdb_vecs; -extern ff_vecs_t easygps_vecs; extern ff_vecs_t quovadis_vecs; -extern ff_vecs_t gpilots_vecs; extern ff_vecs_t saroute_vecs; -extern ff_vecs_t navicache_vecs; -extern ff_vecs_t coastexp_vecs; -extern ff_vecs_t psit_vecs; /* MRCB */ extern ff_vecs_t shape_vecs; -extern ff_vecs_t geoniche_vecs; -extern ff_vecs_t gpl_vecs; -extern ff_vecs_t ozi_vecs; -extern ff_vecs_t nmea_vecs; +extern ff_vecs_t stmsdf_vecs; +extern ff_vecs_t stmwpp_vecs; +extern ff_vecs_t tef_xml_vecs; extern ff_vecs_t text_vecs; -extern ff_vecs_t palmdoc_vecs; -extern ff_vecs_t html_vecs; -extern ff_vecs_t netstumbler_vecs; -extern ff_vecs_t HsaEndeavourNavigator_vecs; -extern ff_vecs_t igc_vecs; -extern ff_vecs_t brauniger_iq_vecs; -extern ff_vecs_t hiketech_vecs; -extern ff_vecs_t glogbook_vecs; -extern ff_vecs_t vcf_vecs; -extern ff_vecs_t overlay_vecs; -extern ff_vecs_t kml_vecs; -extern ff_vecs_t google_vecs; -extern ff_vecs_t maggeo_vecs; -extern ff_vecs_t an1_vecs; +extern ff_vecs_t tiger_vecs; +extern ff_vecs_t tmpro_vecs; extern ff_vecs_t tomtom_vecs; -extern ff_vecs_t tef_xml_vecs; -extern ff_vecs_t ppdb_vecs; +extern ff_vecs_t tpg_vecs; +extern ff_vecs_t tpo2_vecs; +extern ff_vecs_t tpo3_vecs; +extern ff_vecs_t unicsv_vecs; +extern ff_vecs_t vcf_vecs; extern ff_vecs_t vitosmt_vecs; -extern ff_vecs_t gdb_vecs; -extern ff_vecs_t bcr_vecs; -extern ff_vecs_t coto_vecs; +extern ff_vecs_t wfff_xml_vecs; +extern ff_vecs_t xcsv_vecs; +extern ff_vecs_t yahoo_vecs; +extern ff_vecs_t wbt_svecs; +extern ff_vecs_t wbt_fvecs; +extern ff_vecs_t gtc_vecs; +extern ff_vecs_t dmtlog_vecs; static vecs_t vec_list[] = { +#if CSVFMTS_ENABLED /* XCSV must be the first entry in this table. */ { &xcsv_vecs, @@ -96,6 +122,7 @@ vecs_t vec_list[] = { "? Character Separated Values", NULL }, +#endif { &geo_vecs, "geo", @@ -141,7 +168,7 @@ vecs_t vec_list[] = { { &mps_vecs, "mapsource", - "Garmin Mapsource - mps", + "Garmin MapSource - mps", "mps" }, { @@ -160,32 +187,34 @@ vecs_t vec_list[] = { &lowranceusr_vecs, "lowranceusr", "Lowrance USR", - NULL + "usr" }, +#if PDBFMTS_ENABLED { &cetus_vecs, "cetus", "Cetus for Palm/OS", - NULL + "pdb" }, { &copilot_vecs, "copilot", "CoPilot Flight Planner for Palm/OS", - NULL + "pdb" }, { &gpspilot_vecs, "gpspilot", "GPSPilot Tracker for Palm/OS", - NULL + "pdb" }, { &magnav_vec, "magnav", "Magellan NAV Companion for Palm/OS", - NULL + "pdb" }, +#endif /* PDBFMTS_ENABLED */ { &garmin_vecs, "garmin", @@ -201,21 +230,35 @@ vecs_t vec_list[] = { { &tpg_vecs, "tpg", - "National Geographic Topo .tpg", + "National Geographic Topo .tpg (waypoints)", "tpg" }, + { + &tpo2_vecs, + "tpo2", + "National Geographic Topo 2.x .tpo", + "tpo" + }, + { + &tpo3_vecs, + "tpo3", + "National Geographic Topo 3.x/4.x .tpo", + "tpo" + }, { &tmpro_vecs, "tmpro", "TopoMapPro Places File", "tmpro" }, +#if PDBFMTS_ENABLED { &gcdb_vecs, "gcdb", "GeocachingDB for Palm/OS", - NULL + "pdb" }, +#endif { &tiger_vecs, "tiger", @@ -228,18 +271,20 @@ vecs_t vec_list[] = { "EasyGPS binary format", ".loc" }, +#if PDBFMTS_ENABLED { &quovadis_vecs, "quovadis", "Quovadis", - NULL + "pdb" }, { &gpilots_vecs, "gpilots", "GpilotS", - NULL + "pdb" }, +#endif { &saroute_vecs, "saroute", @@ -264,23 +309,25 @@ vecs_t vec_list[] = { "KuDaTa PsiTrex text", NULL }, +#if SHAPELIB_ENABLED { &shape_vecs, "shape", "ESRI shapefile", - NULL + "shp" }, { &geoniche_vecs, "geoniche", "GeoNiche .pdb", - NULL + "pdb" }, +#endif { &gpl_vecs, "gpl", "DeLorme GPL", - NULL + "gpl" }, { &ozi_vecs, @@ -298,24 +345,26 @@ vecs_t vec_list[] = { &text_vecs, "text", "Textual Output", - NULL + "txt" }, { &html_vecs, "html", "HTML Output", - NULL + "html" }, +#if PDBFMTS_ENABLED { &palmdoc_vecs, "palmdoc", "PalmDoc Output", - NULL + "pdb" }, +#endif { &netstumbler_vecs, "netstumbler", - "NetStumbler Summary File", + "NetStumbler Summary File (text)", NULL }, { @@ -336,6 +385,18 @@ vecs_t vec_list[] = { "Brauniger IQ Series Barograph Download", NULL }, + { + &wbt_svecs, + "wbt", + "Wintec WBT-100/200 GPS Download", + "bin" + }, + { + &wbt_fvecs, + "wbt-bin", + "Wintec WBT-100/200 Binary file format", + NULL + }, { &hiketech_vecs, "hiketech", @@ -346,13 +407,13 @@ vecs_t vec_list[] = { &glogbook_vecs, "glogbook", "Garmin Logbook XML", - NULL + "xml" }, { &kml_vecs, "kml", - "Keyhole Markup Language", - NULL + "Google Earth (Keyhole) Markup Language", + "kml" }, { &vcf_vecs, @@ -360,12 +421,14 @@ vecs_t vec_list[] = { "Vcard Output (for iPod)", "vcf", }, +#if 0 { &overlay_vecs, "overlay", "GeoGrid-Viewer", "ovl" }, +#endif { &google_vecs, "google", @@ -396,22 +459,30 @@ vecs_t vec_list[] = { "Map&Guide 'TourExchangeFormat' XML", "xml" }, +#if PDBFMTS_ENABLED { &ppdb_vecs, "pathaway", "PathAway Database for Palm/OS", "pdb" }, +#endif { &vitosmt_vecs, "vitosmt", "Vito Navigator II tracks", "smt" }, + { + &wfff_xml_vecs, + "wfff", + "WiFiFoFum 2.0 for PocketPC XML", + "xml" + }, { &gdb_vecs, "gdb", - "Garmin Mapsource - gdb", + "Garmin MapSource - gdb", "gdb" }, { @@ -420,14 +491,122 @@ vecs_t vec_list[] = { "Motorrad Routenplaner (Map&Guide) .bcr files", "bcr" }, -#if 0 +#if PDBFMTS_ENABLED { &coto_vecs, "coto", "cotoGPS for Palm/OS", - NULL + "pdb" + }, +#endif + { + &ignr_vecs, + "ignrando", + "IGN Rando track files", + "rdn" + }, + { + &stmsdf_vecs, + "stmsdf", + "Suunto Trek Manager (STM) .sdf files", + "sdf" + }, + { + &stmwpp_vecs, + "stmwpp", + "Suunto Trek Manager (STM) WaypointPlus files", + "txt" + }, + { + &msroute_vecs, + "msroute", + "Microsoft AutoRoute 2002 (pin/route reader)", + "axe" + }, + { + &msroute_vecs, + "msroute", + "Microsoft Streets and Trips (pin/route reader)" , + "est" + }, + { + &cst_vecs, + "cst", + "CarteSurTable data file", + "cst" + }, + { + &nmn4_vecs, + "nmn4", + "Navigon Mobile Navigator .rte files", + "rte" + }, +#if PDBFMTS_ENABLED + { + &magpdb_vecs, + "mag_pdb", + "Map&Guide to Palm/OS exported files (.pdb)", + "pdb" }, #endif +#if CSVFMTS_ENABLED + { + &compegps_vecs, + "compegps", + "CompeGPS data files (.wpt/.trk/.rte)", + NULL + }, +#endif //CSVFMTS_ENABLED + { + &yahoo_vecs, + "yahoo", + "Yahoo Geocode API data", + NULL + }, + { + &unicsv_vecs, + "unicsv", + "Universal csv with field structure in first line", + NULL + }, + { + >m_vecs, + "gtm", + "GPS TrackMaker", + "gtm" + }, + { + &gpssim_vecs, + "gpssim", + "Franson GPSGate Simulation", + "gpssim" + }, +#if CSVFMTS_ENABLED + { + &garmin_txt_vecs, + "garmin_txt", + "Garmin MapSource - txt (tab delimited)", + "txt" + }, +#endif // CSVFMTS_ENABLED + { + &axim_gpb_vecs, + "axim_gpb", + "Dell Axim Navigation System (.gpb) file format", + "gpb" + }, + { + >c_vecs, + "gtrnctr", + "Garmin Training Center" + "xml" + }, + { + &dmtlog_vecs, + "dmtlog", + "TrackLogs digital mapping (.trl)", + "trl" + }, { NULL, NULL, @@ -447,6 +626,11 @@ exit_vecs( void ) } if ( vec->vec->args ) { for ( ap = vec->vec->args; ap->argstring; ap++ ) { + if ( ap->defaultvalue && + ( ap->argtype == ARGTYPE_INT ) && + ! isdigit(ap->defaultvalue[0])) { + warning("%s: not an integer\n", ap->argstring); + } if ( ap->argval && *ap->argval ) { xfree(*ap->argval); *ap->argval = NULL; @@ -457,6 +641,83 @@ exit_vecs( void ) } } +void +assign_option(const char *module, arglist_t *ap, const char *val) +{ + char *c; + + if (*ap->argval != NULL) { + xfree(*ap->argval); + *ap->argval = NULL; + } + if (val == NULL) return; + + if (case_ignore_strcmp(val, ap->argstring) == 0) c = ""; + else c = (char *)val; + + switch(ap->argtype & ARGTYPE_TYPEMASK) { + case ARGTYPE_INT: + if (*c == '\0') c = "0"; + else { + int test; + is_fatal(1 != sscanf(c, "%d", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_FLOAT: + if (*c == '\0') c = "0"; + else { + double test; + is_fatal(1 != sscanf(c, "%lf", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_BOOL: + if (*c == '\0') c = "1"; + else { + switch(*c) { + case 'Y': + case 'y': c = "1"; break; + case 'N': + case 'n': c = "0"; break; + default: + if (isdigit(*c)) { + if (*c == '0') c = "0"; + else c = "1"; + } + else { + warning(MYNAME ": Invalid logical value '%s' (%s)!\n", c, module); + c = "0"; + } + break; + } + } + break; + } + + /* for bool options without default: don't set argval if "FALSE" */ + + if (((ap->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) && + (*c == '0') && (ap->defaultvalue == NULL)) { + return; + } + *ap->argval = xstrdup(c); +} + +void +disp_vec_options(const char *vecname, arglist_t *ap) +{ + for (ap = ap; ap && ap->argstring; ap++) { + if (*ap->argval && ap->argval) { + printf("options: module/option=value: %s/%s=\"%s\"", + vecname, ap->argstring, *ap->argval); + if (ap->defaultvalue && (case_ignore_strcmp(ap->defaultvalue, *ap->argval) == 0)) + printf(" (=default)"); + printf("\n"); + } + } +} + ff_vecs_t * find_vec(char *const vecname, char **opts) { @@ -464,12 +725,17 @@ find_vec(char *const vecname, char **opts) style_vecs_t *svec = style_list; char *v = xstrdup(vecname); char *svecname = strtok(v, ","); + int found = 0; + + if (vecname == NULL) { + fatal("A format name is required.\n"); + } while (vec->vec) { arglist_t *ap; char *res; - if (strcmp(svecname, vec->name)) { + if (case_ignore_strcmp(svecname, vec->name)) { vec++; continue; } @@ -477,42 +743,36 @@ find_vec(char *const vecname, char **opts) res = strchr(vecname, ','); if (res) { *opts = strchr(vecname, ',')+1; - - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++){ - char *opt = NULL; - if ( *ap->argval ) xfree(*ap->argval); - - opt = get_option(*opts, ap->argstring); - if ( opt ) { - *ap->argval = opt; - } - else if ( ap->defaultvalue ) { - *ap->argval = xstrdup( - ap->defaultvalue ); - } - else { - *ap->argval = NULL; - } - } - } } else { *opts = NULL; - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++){ - if ( *ap->argval ) xfree(*ap->argval); - - if ( ap->defaultvalue ) { - *ap->argval = xstrdup( - ap->defaultvalue ); - } - else { - *ap->argval = NULL; + } + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + char *opt; + + if ( res ) { + opt = get_option(*opts, ap->argstring); + if ( opt ) { + found = 1; + assign_option(svecname, ap, opt); + xfree(opt); + continue; } } + opt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + if (opt == NULL) opt = ap->defaultvalue; + assign_option(vec->name, ap, opt); } } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + if (global_opts.debug_level >= 1) + disp_vec_options(vec->name, vec->vec->args); + xcsv_setup_internal_style( NULL ); xfree(v); return vec->vec; @@ -527,7 +787,7 @@ find_vec(char *const vecname, char **opts) arglist_t *ap; char *res; - if (strcmp(svecname, svec->name)) { + if (case_ignore_strcmp(svecname, svec->name)) { svec++; continue; } @@ -535,14 +795,37 @@ find_vec(char *const vecname, char **opts) res = strchr(vecname, ','); if (res) { *opts = strchr(vecname, ',') + 1; - if (vec_list[0].vec->args) { - for (ap = vec_list[0].vec->args; ap->argstring; ap++) { - *ap->argval = get_option(*opts, ap->argstring); - } - } } else { *opts = NULL; } + + if (vec_list[0].vec->args) { + for (ap = vec_list[0].vec->args; ap->argstring; ap++) { + char *opt; + + if ( res ) { + opt = get_option(*opts, ap->argstring); + if ( opt ) { + found = 1; + assign_option(svecname, ap, opt); + xfree(opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); + if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + if (opt == NULL) opt = ap->defaultvalue; + assign_option(svec->name, ap, opt); + } + } + + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, svec->name); + } + + if (global_opts.debug_level >= 1) + disp_vec_options(svec->name, vec_list[0].vec->args); + xcsv_setup_internal_style(svec->style_buf); xfree(v); @@ -581,8 +864,8 @@ get_option(const char *iarglist, const char *argname) arglen = strlen(argname); arglist = xstrdup(iarglist); - for (arg = arglist; argp = strtok(arg, ","); arg = NULL) { - if (0 == strncmp(argp, argname, arglen)) { + for (arg = arglist; argp = strtok(arg, ","), NULL != argp; arg = NULL) { + if (0 == case_ignore_strncmp(argp, argname, arglen)) { /* * If we have something of the form "foo=bar" * return "bar". Otherwise, we assume we have @@ -645,6 +928,9 @@ sort_and_unify_vecs(int *ctp) /* Normal vecs are easy; populate the first part of the array. */ for (vec = vec_list; vec->vec; vec++, i++) { svp[i] = vec; + if (svp[i]->parent == NULL) { + svp[i]->parent = svp[i]->name; + } } /* Walk the style list, parse the entries, dummy up a "normal" vec */ @@ -658,10 +944,18 @@ sort_and_unify_vecs(int *ctp) /* Reset file type to inherit ff_type from xcsv for everything * except the xcsv format itself, which we leave as "internal" */ - if (strcmp(svec->name, "xcsv")) + if (case_ignore_strcmp(svec->name, "xcsv")) { svp[i]->vec->type = xcsv_file.type; + /* Skip over the first help entry for all but the + * actual 'xcsv' format - so we don't expose the + * 'full path to xcsv style file' argument to any + * GUIs for an internal format. + */ + svp[i]->vec->args++; + } svp[i]->desc = xcsv_file.description; + svp[i]->parent = "xcsv"; } /* Now that we have everything in an array, alphabetize them */ qsort(svp, vc, sizeof(*svp), alpha); @@ -670,6 +964,7 @@ sort_and_unify_vecs(int *ctp) return svp; } +#define VEC_FMT " %-20.20s %-.50s\n" void disp_vecs(void) @@ -680,7 +975,6 @@ disp_vecs(void) int i = 0; svp = sort_and_unify_vecs(&vc); -#define VEC_FMT " %-20.20s %-.50s\n" for (i=0;ivec->type == ff_type_internal ) { continue; @@ -688,8 +982,39 @@ disp_vecs(void) printf(VEC_FMT, svp[i]->name, svp[i]->desc); for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { if ( !(ap->argtype & ARGTYPE_HIDDEN)) - printf(" %-18.18s %-.50s %s\n", - ap->argstring, ap->helpstring, + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree (svp); + return; +} + +void +disp_vec( const char *vecname ) +{ + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0;iname, vecname )) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); } } @@ -726,6 +1051,43 @@ disp_v2(ff_vecs_t *v) putchar('\t'); } +const char * +name_option(long type) +{ + const char *at[] = { + "unknown", + "integer", + "float", + "string", + "boolean", + "file", + "outfile" + }; + + if ((type & ARGTYPE_TYPEMASK) <= 6) { + return at[type & ARGTYPE_TYPEMASK]; + } + return at[0]; +} + +static void +disp_v3(vecs_t *vec) +{ + arglist_t *ap; + + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if ( !(ap->argtype & ARGTYPE_HIDDEN)) + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + } +} + /* * Display the available formats in a format that's easy to machine * parse. Typically invoked by programs like graphical wrappers to @@ -742,6 +1104,7 @@ disp_formats(int version) case 0: case 1: case 2: + case 3: svp = sort_and_unify_vecs(&vc); for (i=0;i= 2) { disp_v2(vec->vec); } - printf("%s\t%s\t%s\n", vec->name, + printf("%s\t%s\t%s%s%s\n", vec->name, vec->extension? vec->extension : "", - vec->desc); + vec->desc, + version >= 3 ? "\t" : "", + version >= 3 ? vec->parent : ""); + if (version >= 3) { + disp_v3(vec); + } } xfree (svp); break; diff --git a/vitosmt.c b/vitosmt.c index f7e1ad555..4a9bedf64 100644 --- a/vitosmt.c +++ b/vitosmt.c @@ -26,6 +26,7 @@ #define MYNAME "vitosmt" #include "defs.h" +#include "grtcirc.h" static FILE *infile =0; static FILE *ofs =0; @@ -52,11 +53,8 @@ static double ReadDouble(FILE * f) { unsigned char buffer[8] = "\0\0\0\0\0\0\0\0"; - double result=0; - fread(buffer, sizeof (buffer), 1, f); - le_read64(&result,buffer); - return result; + return le_read_double(buffer ); } @@ -74,11 +72,8 @@ static void WriteDouble(void* ptr, double d) { unsigned char result[8]="\0\0\0\0\0\0\0\0"; - - le_read64(result, &d); + le_write_double(result,d); memcpy(ptr, result, 8); - - return; } @@ -108,7 +103,7 @@ vitosmt_read(void) double lonrad =0; double elev =0; unsigned char* timestamp =0; - struct tm tmStruct ={0,0,0,0,0,0,0,0,0}; + struct tm tmStruct; double seconds =0.0; double speed =0.0; double course =0.0; @@ -118,7 +113,8 @@ vitosmt_read(void) unsigned char gpssats =0; int serial =0; - + + memset(&tmStruct, 0, sizeof(tmStruct)); /* * 24 bytes header */ @@ -174,8 +170,8 @@ vitosmt_read(void) wpt_tmp = waypt_new(); - wpt_tmp->latitude =(latrad * 180) / M_PI; - wpt_tmp->longitude =(lonrad * 180) / M_PI; + wpt_tmp->latitude =DEG(latrad); + wpt_tmp->longitude =DEG(lonrad); wpt_tmp->altitude =elev; tmStruct.tm_year =timestamp[0]+100; @@ -235,7 +231,7 @@ vitosmt_read(void) route_head = route_head_alloc(); track_add_head(route_head); } - route_add_wpt(route_head, wpt_tmp); + track_add_wpt(route_head, wpt_tmp); } xfree(timestamp); @@ -269,9 +265,9 @@ vitosmt_waypt_pr(const waypoint *waypointp) ++count; workbuffer = xcalloc(vitosmt_datasize,1); - WriteDouble(&workbuffer[position], (M_PI*waypointp->latitude)/180 ); + WriteDouble(&workbuffer[position], RAD(waypointp->latitude) ); position += sizeof(double); - WriteDouble(&workbuffer[position], (M_PI*waypointp->longitude)/180 ); + WriteDouble(&workbuffer[position], RAD(waypointp->longitude) ); position += sizeof(double); if ( waypointp->altitude-1 > unknown_alt) WriteDouble(&workbuffer[position], waypointp->altitude ); @@ -409,5 +405,6 @@ ff_vecs_t vitosmt_vecs = { vitosmt_read, vitosmt_write, NULL, - NULL + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/vmem.c b/vmem.c index 32eda7aae..f1834f1c2 100644 --- a/vmem.c +++ b/vmem.c @@ -41,7 +41,7 @@ vmem_alloc(size_t size, int flags) void vmem_free(vmem_t *vm) { - xfree(vm->mem); + if (vm->mem) xfree(vm->mem); vm->mem = NULL; vm->size = 0; return; diff --git a/waypt.c b/waypt.c index f86958e3a..57985ed22 100644 --- a/waypt.c +++ b/waypt.c @@ -21,10 +21,11 @@ #include #include "defs.h" +#include "cet_util.h" queue waypt_head; static unsigned int waypt_ct; -static void *mkshort_handle; +static short_handle mkshort_handle; void waypt_init(void) @@ -86,6 +87,11 @@ waypt_add(waypoint *wpt) ENQUEUE_TAIL(&waypt_head, &wpt->Q); waypt_ct++; + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal ("Invalid latitude %f in waypoint.\n", wpt->latitude); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal ("Invalid longitude %f in waypoint.\n", wpt->latitude); + /* * Some input may not have one or more of these types so we * try to be sure that we have these fields even if just by @@ -134,8 +140,8 @@ waypt_new(void) wpt = (waypoint *) xcalloc(sizeof (*wpt), 1); wpt->altitude = unknown_alt; - wpt->course = -999.0; - wpt->speed = -999.0; + wpt->course = unknown_course; + wpt->speed = unknown_speed; wpt->fix = fix_unknown; wpt->sat = -1; @@ -165,7 +171,7 @@ waypt_disp(const waypoint *wpt) printposn(wpt->longitude,0); if ( wpt->description ) { - tmpdesc = str_utf8_to_ascii( wpt->description); + tmpdesc = xstrdup( wpt->description); printf("%s/%s", global_opts.synthesize_shortnames ? mkshort(mkshort_handle, tmpdesc) : @@ -207,6 +213,40 @@ waypt_disp_all(waypt_cb cb) } } +void +waypt_init_bounds(bounds *bounds) +{ + /* Set data out of bounds so that even one waypoint will reset */ + bounds->max_lat = -9999; + bounds->max_lon = -9999; + bounds->min_lat = 9999; + bounds->min_lon = 9999; +} + +int +waypt_bounds_valid(bounds *bounds) +{ + /* Returns true if bb has any 'real' data in it */ + return bounds->max_lat > -9999; +} + +/* + * Recompund bounding box based on new position point. + */ +void +waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp) +{ + if (waypointp->latitude > bounds->max_lat) + bounds->max_lat = waypointp->latitude; + if (waypointp->longitude > bounds->max_lon) + bounds->max_lon = waypointp->longitude; + if (waypointp->latitude < bounds->min_lat) + bounds->min_lat = waypointp->latitude; + if (waypointp->longitude < bounds->min_lon) + bounds->min_lon = waypointp->longitude; +} + + /* * Makes another pass over the data to compute bounding * box data and populates bounding box information. @@ -218,22 +258,11 @@ waypt_compute_bounds(bounds *bounds) queue *elem, *tmp; waypoint *waypointp; - /* Set data out of bounds so that even one waypoint will reset */ - bounds->max_lat = -9999; - bounds->max_lon = -9999; - bounds->min_lat = 9999; - bounds->min_lon = 9999; + waypt_init_bounds(bounds); QUEUE_FOR_EACH(&waypt_head, elem, tmp) { waypointp = (waypoint *) elem; - if (waypointp->latitude > bounds->max_lat) - bounds->max_lat = waypointp->latitude; - if (waypointp->longitude > bounds->max_lon) - bounds->max_lon = waypointp->longitude; - if (waypointp->latitude < bounds->min_lat) - bounds->min_lat = waypointp->latitude; - if (waypointp->longitude < bounds->min_lon) - bounds->min_lon = waypointp->longitude; + waypt_add_to_bounds(bounds, waypointp); } } @@ -301,7 +330,9 @@ waypt_flush( queue *head ) QUEUE_FOR_EACH(head, elem, tmp) { waypoint *q = (waypoint *) dequeue(elem); waypt_free(q); - waypt_ct--; + if (head == &waypt_head) { + waypt_ct--; + } } } @@ -309,7 +340,45 @@ void waypt_flush_all() { if ( mkshort_handle ) { - mkshort_del_handle( mkshort_handle ); + mkshort_del_handle( &mkshort_handle ); } waypt_flush(&waypt_head); } + +void +waypt_backup(signed int *count, queue **head_bak) +{ + queue *elem, *tmp, *qbackup; + waypoint *wpt; + int no = 0; + + qbackup = (queue *) xcalloc(1, sizeof(*qbackup)); + QUEUE_INIT(qbackup); + + QUEUE_MOVE(qbackup, &waypt_head); + QUEUE_INIT(&waypt_head); + + waypt_ct = 0; + + QUEUE_FOR_EACH(qbackup, elem, tmp) + { + wpt = (waypoint *)elem; + waypt_add(waypt_dupe(wpt)); + no++; + } + + *head_bak = qbackup; + *count = no; +} + +void +waypt_restore(signed int count, queue *head_bak) +{ + if (head_bak == NULL) return; + + waypt_flush(&waypt_head); + QUEUE_INIT(&waypt_head); + QUEUE_MOVE(&waypt_head, head_bak); + waypt_ct = count; + xfree(head_bak); +} diff --git a/wbt-200.c b/wbt-200.c new file mode 100644 index 000000000..e497c619c --- /dev/null +++ b/wbt-200.c @@ -0,0 +1,651 @@ +/* + * Serial download of track data from a Wintec WBT-200. + * + * Copyright (C) 2006 Andy Armstrong + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "defs.h" +#include "gbser.h" +#include "grtcirc.h" +#include + +#define MYNAME "WBT-100/200" +#define NL "\x0D\x0A" + +#define BAUD 9600 +#define TIMEOUT 5000 + +#define RECLEN_V1 12 +#define RECLEN_V2 16 + +/* Used to sanity check data - from + * http://hypertextbook.com/facts/2001/DanaWollman.shtml + * The MAXALT check doesn't need to be enabled unless there's + * a format with larger records than V2. + */ +/*#define MAXALT 120000*/ + +#define _MAX(a, b) ((a) > (b) ? (a) : (b)) +#define RECLEN_MAX _MAX(RECLEN_V1, RECLEN_V2) + +/* The formats here must be in ascending record length order so that + * each format identification attempt can read more data from the + * device if necessary. If that proves to be a bad order to try the + * heuristics the format matching code will have to be rejigged. + */ +static struct { + size_t reclen; +} fmt_version[] = { + { RECLEN_V1 }, + { RECLEN_V2 }, + { 0 } +}; + +/* Number of lines to skip while waiting for an ACK from a command. I've seen + * conversations with up to 30 lines of cruft before the response so 50 isn't + * too crazy. + */ +#define RETRIES 50 + +/* + A conversation looks like this + + >> $PFST,FIRMWAREVERSION + << $PFST,FIRMWAREVERSION,WBT200,3,31,6090,R2*77 + >> $PFST,NORMAL + << $PFST,NORMAL,*02 + >> $PFST,READLOGGER + << $PFST,READLOGGER,*17 + << 0xFFFF, , 0xFFFF + << (length + 1) * 12 or 16 bytes of data + << ==== + >> $PFST,NORMAL + << $PFST,NORMAL,*02 +*/ + +static void *fd; +static FILE *fl; +static char *port; +static char *erase; + +struct buf_chunk { + struct buf_chunk *next; + size_t size; + size_t used; + /* data follows in memory */ +}; + +#define buf_CHUNK_DATA(c) \ + ((void *) ((struct buf_chunk *) (c) + 1)) + +#define buf_CHUNK_PTR(c, offset) \ + ((void *) ((char *) buf_CHUNK_DATA(c) + (offset))) + +struct buf_head { + struct buf_chunk *head; + struct buf_chunk *tail; + size_t alloc; + size_t used; + /* read position */ + struct buf_chunk *current; + unsigned long offset; +}; + +struct read_state { + route_head *route_head; + double plat, plon; /* previous point */ + time_t ptim; + unsigned wpn; + + struct buf_head data; +}; + +static void db(int l, const char *msg, ...) { + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); +} + +/* Growable buffer support. TODO: Put this in a separate file and + * tidy up its interface. + */ + +static void buf_init(struct buf_head *h, size_t alloc) { + h->head = NULL; + h->tail = NULL; + h->alloc = alloc; + h->used = 0; +} + +static void buf_empty(struct buf_head *h) { + struct buf_chunk *chunk, *next; + for (chunk = h->head; chunk; chunk = next) { + next = chunk->next; + xfree(chunk); + } + h->head = NULL; + h->tail = NULL; + h->used = 0; +} + +static void buf_rewind(struct buf_head *h) { + h->current = h->head; + h->offset = 0; +} + +static size_t buf_read(struct buf_head *h, void *data, size_t len) { + char *bp = data; + + while (len != 0 && h->current != NULL) { + size_t avail = h->current->used - h->offset; + if (avail > len) { avail = len; } + + memcpy(bp, buf_CHUNK_PTR(h->current, h->offset), avail); + h->offset += avail; + bp += avail; + len -= avail; + + if (h->offset == h->current->used) { + h->current = h->current->next; + h->offset = 0; + } + } + + return bp - (char *) data; +} + +static void buf_extend(struct buf_head *h, size_t amt) { + struct buf_chunk *c; + size_t sz = amt + sizeof(struct buf_chunk); + if (c = xmalloc(sz), NULL == c) { + fatal(MYNAME ": Can't allocate %lu bytes for buffer", (unsigned long) sz); + } + + c->next = NULL; + c->size = amt; + c->used = 0; + + if (NULL == h->head) { + h->head = c; + } else { + h->tail->next = c; + } + + h->tail = c; +} + +static void buf_write(struct buf_head *h, const void *data, size_t len) { + size_t avail; + const char *bp = data; + + h->used += len; + + if (NULL == h->tail) { + buf_extend(h, h->alloc); + } + + for (;;) { + avail = h->tail->size - h->tail->used; + if (avail > len) { avail = len; } + + memcpy((char *) buf_CHUNK_PTR(h->tail, h->tail->used), bp, avail); + h->tail->used += avail; + bp += avail; + len -= avail; + if (len == 0) { + break; + } + buf_extend(h, h->alloc); + } +} + +static void rd_drain() { + if (gbser_flush(fd)) { + fatal(MYNAME ": Comm error\n"); + } +} + +static void rd_line(char *buf, int len) { + int rc; + if (rc = gbser_read_line(fd, buf, len, TIMEOUT, 0x0A, 0x0D), rc != gbser_OK) { + fatal(MYNAME ": Read error (%d)\n", rc); + } +} + +static void wr_cmd(const char *cmd) { + int rc; + db(3, "Sending: %s\n", cmd); + if (rc = gbser_print(fd, cmd), gbser_OK != rc) { + fatal(MYNAME ": Write error (%d)\n", rc); + } +} + +static void rd_init(const char *fname) { + port = xstrdup(fname); + + db(1, "Opening port...\n"); + if ((fd = gbser_init(port), NULL == fd) || + gbser_set_port(fd, BAUD, 8, 0, 1)) { + fatal(MYNAME ": Can't initialise port \"%s\"\n", port); + } +} + +static void rd_deinit(void) { + db(1, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); +} + +static void rd_buf(void *buf, int len) { + int rc; + if (rc = gbser_read_wait(fd, buf, len, TIMEOUT), rc < 0) { + fatal(MYNAME ": Read error (%d)\n", rc); + } else if (rc < len) { + fatal(MYNAME ": Read timout\n"); + } +} + +static void file_init(const char *fname) { + db(1, "Opening file...\n"); + if (fl = fopen(fname, "rb"), NULL == fl) { + fatal(MYNAME ": Can't open file '%s'\n", fname); + } +} + +static void file_deinit(void) { + db(1, "Closing file...\n"); + fclose(fl); +} + +static int starts_with(const char *buf, const char *pat) { + return memcmp(buf, pat, strlen(pat)) == 0; +} + +/* Send a command then wait for a line starting with the command string + * to be returned. + */ +static void do_cmd(const char *cmd, const char *expect, char *buf, int len) { + int try; + + rd_drain(); + wr_cmd(cmd); + wr_cmd(NL); + + db(2, "Cmd: %s\n", cmd); + + /* We may need to skip a load of data to start with - the unit streams + * NMEA data all the time so it's highly likely that it'll be in the + * middle of an NMEA sentence when we start listening. + */ + for (try = 0; try < RETRIES; try++) { + rd_line(buf, len); + if (starts_with(buf, expect)) { + db(2, "Got: %s\n", buf); + return; + } + db(2, "Skip %d: %s\n", try, buf); + } + + fatal(MYNAME ": Bad response from unit\n"); +} + +/* Issue a command that expects the same string to be echoed + * back as an ACK + */ +static void do_simple(const char *cmd, char *buf, int len) { + do_cmd(cmd, cmd, buf, len); +} + +/* Decompose binary date into discreet fields */ +#define _SPLIT_DATE(tim) \ + int sec = (((tim) >> 0) & 0x3F); \ + int min = (((tim) >> 6) & 0x3F); \ + int hour = (((tim) >> 12) & 0x1F); \ + int mday = (((tim) >> 17) & 0x1F); \ + int mon = (((tim) >> 22) & 0x0F); \ + int year = (((tim) >> 26) & 0x3F); + +static time_t decode_date(gbuint32 tim) { + _SPLIT_DATE(tim) + struct tm t; + + t.tm_sec = sec; + t.tm_min = min; + t.tm_hour = hour; + t.tm_mday = mday; + t.tm_mon = mon - 1; + t.tm_year = year + 100; + + return mkgmtime(&t); +} + +static int check_date(gbuint32 tim) { + _SPLIT_DATE(tim) + + /* Sanity check the date. We don't allow years prior to 2004 because zero in + * those bits will usually indicate that we have an altitude instead of a + * date (i.e. that the data is the new format that uses 16 byte records). + */ + return sec < 60 && min < 60 && hour < 24 && + mday > 0 && mday <= 31 && mon > 0 && mon <= 12 && year >= 4; +} + +static int data_chunk(struct read_state *st, const void *buf, int fmt) { + char wp_name[20]; + gbuint32 tim; + double lat, lon, alt; + time_t rtim; + waypoint *wpt = NULL; + const char *bp = buf; + size_t buf_used = fmt_version[fmt].reclen; + + tim = le_read32(bp + 0); + + lat = (double) ((gbint32) le_read32(bp + 4)) / 10000000; + lon = (double) ((gbint32) le_read32(bp + 8)) / 10000000; + + /* Handle extra fields in longer records here. */ + if (buf_used >= 16) { + alt = (double) le_read32(bp + 12) / 10; + } else { + alt = unknown_alt; + } + + rtim = decode_date(tim); + + if (lat >= 100) { + /* Start new track in the northern hemisphere */ + lat -= 100; + st->route_head = NULL; + } else if (lat <= -100) { + /* Start new track in the southern hemisphere */ + /* This fix courtesy of Anton Frolich */ + lat += 100; + st->route_head = NULL; + } else { + /* TODO: Should this code execute for /every/ waypoint - even the first in + * a track? Presumably it should because the first point looks as valid as + * any other. + */ + + wpt = waypt_new(); + + wpt->latitude = lat;; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->creation_time = rtim; + wpt->centiseconds = 0; + + sprintf(wp_name, "WP%04d", ++st->wpn); + wpt->shortname = xstrdup(wp_name); + + if (NULL == st->route_head) { + db(1, "New Track\n"); + st->route_head = route_head_alloc(); + track_add_head(st->route_head); + } + + track_add_wpt(st->route_head, wpt); + } + + st->ptim = rtim; + st->plat = lat; + st->plon = lon; + + return 1; +} + +/* Return true iff the data appears valid with the specified record length */ +static int is_valid(struct buf_head *h, int fmt) { + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; + + buf_rewind(h); + + db(2, "Checking %lu bytes of data against format %d\n", h->used, fmt); + + for (;;) { + size_t got = buf_read(h, buf, reclen); + gbuint32 tim; + /* Don't mind odd bytes at the end - we may + * be examining an incomplete dataset. + */ + if (got != reclen) { + break; + } + + tim = le_read32(buf + 0); + if (!check_date(tim)) { + return 0; + } + + if (reclen > 12) { +#ifdef MAXALT + gbuint32 alt = le_read32(buf + 12); + if (alt > MAXALT * 10) { + return 0; + } +#endif + } + } + + return 1; +} + +static void process_data(struct read_state *pst, int fmt) { + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; + + buf_rewind(&pst->data); + + db(2, "Processing %lu bytes of data using format %d\n", pst->data.used, fmt); + + for (;;) { + size_t got = buf_read(&pst->data, buf, reclen); + if (got != reclen) { + break; + } + data_chunk(pst, buf, fmt); + } +} + +static void state_init(struct read_state *pst) { + pst->route_head = NULL; + pst->wpn = 0; + + buf_init(&pst->data, RECLEN_V1 * RECLEN_V2); +} + +static void state_empty(struct read_state *pst) { + buf_empty(&pst->data); + state_init(pst); +} + +static void file_read(void) { + char buf[512]; + size_t rc; + struct read_state st; + int fmt; + + state_init(&st); + + /* Read the whole file into the buffer */ + rc = fread(buf, 1, sizeof(buf), fl); + while (rc != 0) { + buf_write(&st.data, buf, rc); + rc = fread(buf, 1, sizeof(buf), fl); + } + + if (!feof(fl)) { + fatal(MYNAME ": Read error"); + } + + /* Try to guess the data format */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + if ((st.data.used % reclen) == 0 && is_valid(&st.data, fmt)) { + break; + } + } + + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format"); + } + + process_data(&st, fmt); + + state_empty(&st); +} + +static void want_bytes(struct buf_head *h, size_t len) { + char buf[512]; + + db(3, "Reading %lu bytes from device\n", (unsigned long) len); + + while (len > 0) { + size_t want = sizeof(buf); + if (want > len) { want = len; } + rd_buf(buf, want); + buf_write(h, buf, want); + len -= want; + } +} + +static void data_read(void) { + /* Awooga! Awooga! Statically allocated buffer danger! + * Actually, it's OK because rd_line can read arbitrarily + * long lines returning only the first N characters + */ + char line_buf[100]; + int fmt; + unsigned long count; + struct read_state st; + + state_init(&st); + + /* We could potentially parse the version string to find out which + * data format to use - but it's not clear how the version string + * will increment in the future - so just now it's more future- + * proof to rely on analysing the data. We need to be able to do + * that with files anyway - because they're not versioned. + */ + do_simple("$PFST,FIRMWAREVERSION", line_buf, sizeof(line_buf)); + + do_simple("$PFST,NORMAL", line_buf, sizeof(line_buf)); + do_simple("$PFST,READLOGGER", line_buf, sizeof(line_buf)); + + /* Now we're into binary mode */ + rd_buf(line_buf, 6); /* six byte header */ + count = le_read16(line_buf + 2) + 1; + if (count == 0x10000) { + count = 0; + } + + db(3, "%lu points available\n", count); + + /* Loop through the known formats requesting more data from the + * device each time. When the device contains only a single + * point the first format will get a false positive - so we'll + * lose the altitude data. + */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + size_t want = reclen * count; + + if (want < st.data.used) { + fatal(MYNAME ": Internal error: formats not ordered in ascending size order"); + } + + db(3, "Want %lu bytes of data\n", (unsigned long) want); + + /* Top up the buffer */ + want_bytes(&st.data, want - st.data.used); + + /* And see if it's valid */ + if (is_valid(&st.data, fmt)) { + break; + } + } + + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format"); + } + + process_data(&st, fmt); + + /* Erase data? */ + + if (*erase != '0') { + int f; + db(1, "Erasing data\n"); + for (f = 27; f <= 31; f++) { + sprintf(line_buf, "$PFST,REMOVEFILE,%d", f); + do_cmd(line_buf, "$PFST,REMOVEFILE", line_buf, sizeof(line_buf)); + } + db(1, "Reclaiming free space\n"); + for (f = 0; f <= 3; f++) { + sprintf(line_buf, "$PFST,FFSRECLAIM,%d", f); + do_cmd(line_buf, "$PFST,FFSRECLAIM", line_buf, sizeof(line_buf)); + } + } + + do_simple("$PFST,NORMAL", line_buf, sizeof(line_buf)); + + state_empty(&st); +} + +static arglist_t wbt_sargs[] = { + { "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +ff_vecs_t wbt_svecs = { + ff_type_serial, + { ff_cap_none, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + wbt_sargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ +}; + +static arglist_t wbt_fargs[] = { + ARG_TERMINATOR +}; + +ff_vecs_t wbt_fvecs = { + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + wbt_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ +}; diff --git a/wfff_xml.c b/wfff_xml.c new file mode 100644 index 000000000..a8177a581 --- /dev/null +++ b/wfff_xml.c @@ -0,0 +1,295 @@ +/* + Copyright (C) 2006 Etienne Tasse etasse@yahoo.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include "defs.h" +#include "xmlgeneric.h" + +/* argument storage */ +static char * aicicon =0; +static char * aioicon =0; +static char * ahcicon =0; +static char * ahoicon =0; +static char * snmac =0; + +static +arglist_t wfff_xml_args[] = { + {"aicicon", &aicicon, "Infrastructure closed icon name", + "Red Square", ARGTYPE_STRING }, + {"aioicon", &aioicon, "Infrastructure open icon name", + "Green Square", ARGTYPE_STRING }, + {"ahcicon", &ahcicon, "Ad-hoc closed icon name", + "Red Diamond", ARGTYPE_STRING }, + {"ahoicon", &ahoicon, "Ad-hoc open icon name", + "Green Diamond", ARGTYPE_STRING }, + {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, + {0, 0, 0, 0, 0} +}; + +#define xfreez(p) { if (p) xfree(p); p=0; } + +#define MYNAME "wfff_xml" +#define MY_CBUF 4096 + +#if ! HAVE_LIBEXPAT +void +wfff_xml_rd_init(const char *fname) +{ + fatal(MYNAME ": This build excluded WFFF_XML support because expat was not installed.\n"); +} +void +wfff_xml_read(void) +{ +} +void +wfff_xml_rd_deinit(void) +{ +} + +#else + +static xg_callback wfff_s, wfff_e; +static xg_callback wfff_wep, wfff_mac, wfff_type; +static xg_callback wfff_ssid, wfff_chan; +static xg_callback wfff_mnrssi, wfff_mxrssi; +static xg_callback wfff_first, wfff_last; +static xg_callback wfff_hdop, wfff_lat, wfff_lon; + +static +xg_tag_mapping loc_map[] = { + { wfff_s, cb_start, "/DocumentElement/AP" }, + { wfff_e, cb_end, "/DocumentElement/AP" }, + { wfff_wep, cb_cdata, "/DocumentElement/AP/WEP" }, + { wfff_mac, cb_cdata, "/DocumentElement/AP/MAC" }, + { wfff_ssid, cb_cdata, "/DocumentElement/AP/SSID" }, + { wfff_type, cb_cdata, "/DocumentElement/AP/Type" }, + { wfff_mnrssi, cb_cdata, "/DocumentElement/AP/MinRSSI" }, + { wfff_mxrssi, cb_cdata, "/DocumentElement/AP/MaxRSSI" }, + { wfff_chan, cb_cdata, "/DocumentElement/AP/Channel" }, + { wfff_first, cb_cdata, "/DocumentElement/AP/FirstSeen" }, + { wfff_last, cb_cdata, "/DocumentElement/AP/LastSeen" }, + { wfff_hdop, cb_cdata, "/DocumentElement/AP/HDOP" }, + { wfff_lat, cb_cdata, "/DocumentElement/AP/Lat" }, + { wfff_lon, cb_cdata, "/DocumentElement/AP/Lon" }, + { 0,0,0 } +}; + +/* work variables for wfff_xxx */ +static char* ap_mac =0; +static char* ap_ssid =0; +static char* ap_type =0; +static char* ap_wep =0; +static int ap_chan =0; +static time_t ap_first =0; +static char* ap_last =0; +static float ap_mnrssi =0.0; +static float ap_mxrssi =0.0; +static float ap_hdop =0.0; +static double ap_lat =0.0; +static double ap_lon =0.0; + +/* Start of AP block */ +void wfff_s(const char *args, const char **unused) +{ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + ap_mnrssi=0.0; + ap_mxrssi=0.0; + ap_chan=0; + ap_hdop=0.0; + ap_first=0; + ap_last=0; + ap_lat=0.0; + ap_lon=0.0; +} + +void wfff_mac(const char *args, const char **unused) +{ + if (args) ap_mac = xstrdup(args); +} + +void wfff_ssid(const char *args, const char **unused) +{ + if (args) ap_ssid = xstrdup(args); +} + +void wfff_type(const char *args, const char **unused) +{ + if (args) ap_type = xstrdup(args); +} + +void wfff_mnrssi(const char *args, const char **unused) +{ + if (args) ap_mnrssi = atof(args); +} + +void wfff_mxrssi(const char *args, const char **unused) +{ + if (args) ap_mxrssi = atof(args); +} + +void wfff_chan(const char *args, const char **unused) +{ + if (args) ap_chan = atoi(args); +} + +void wfff_first(const char *args, const char **unused) +{ + if (args) { + ap_first = xml_parse_time(args); + } +} + +void wfff_last(const char *args, const char **unused) +{ + if (args) ap_last = xstrdup(args); +} + +void wfff_wep(const char *args, const char **unused) +{ + if (args) ap_wep = xstrdup(args); +} + +void wfff_hdop(const char *args, const char **unused) +{ + if (args) ap_hdop = atof(args); +} + +void wfff_lat(const char *args, const char **unused) +{ + if (args) ap_lat = atof(args); +} + +void wfff_lon(const char *args, const char **unused) +{ + if (args) ap_lon = atof(args); +} + +/* End of AP Block, set waypoint and add */ +static long tosscount=0; + +void wfff_e(const char *args, const char **unused) +{ + waypoint* wpt_tmp =0; + char desc[255] ="\0"; + + if ((ap_hdop>=1)&&(ap_hdop<50)) // Discard invalid GPS fix + { + wpt_tmp = xcalloc(sizeof(*wpt_tmp), 1); + + if ( snmac ) { + wpt_tmp->shortname = xstrdup(ap_mac); + } else { + wpt_tmp->shortname = xstrdup(ap_ssid); + } + + snprintf(desc, sizeof desc, + "%s/%s/WEP %s/Ch %d/%2.0fdB/%2.0fdB/%s", + (snmac?ap_ssid:ap_mac), ap_type, ap_wep, + ap_chan, ap_mnrssi, ap_mxrssi, ap_last); + wpt_tmp->description = xstrdup(desc); + + wpt_tmp->latitude = ap_lat; + wpt_tmp->longitude = ap_lon; + wpt_tmp->hdop = ap_hdop; + wpt_tmp->altitude = unknown_alt; + wpt_tmp->fix = fix_unknown; + + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + if (case_ignore_strncmp(ap_wep,"On",2)==0) { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aicicon); /* Infra Closed */ + } else { + wpt_tmp->icon_descr = xstrdup(ahcicon); /* AdHoc Closed */ + } + } else { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aioicon); /* Infra Open */ + } else { + wpt_tmp->icon_descr = xstrdup(ahoicon); /* AdHoc Open */ + } + } + + wpt_tmp->creation_time = ap_first; + + waypt_add(wpt_tmp); + + } else { + tosscount++; + } + + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + +} + + +void +wfff_xml_rd_init(const char *fname) +{ + tosscount = 0; + + xml_init(fname, loc_map, NULL); +} + +void +wfff_xml_read(void) +{ + xml_read(); +} + +void +wfff_xml_rd_deinit(void) +{ + + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + + xml_deinit(); + + if (tosscount) { + warning("Warning: %s reading file. Threw away %ld invalid entries.\n", + MYNAME, tosscount ); + } + +} + +#endif + +ff_vecs_t wfff_xml_vecs = { + ff_type_file, + {ff_cap_read, ff_cap_none, ff_cap_none}, + wfff_xml_rd_init, + 0, + wfff_xml_rd_deinit, + 0, + wfff_xml_read, + 0, + 0, + wfff_xml_args +}; diff --git a/win32/GPSBabelGUI.exe b/win32/GPSBabelGUI.exe index 03773b1cbfdd790193a957a95cedee5912e27121..044c408bb8401bcb7a509fe450ff109917e10478 100644 GIT binary patch literal 1002504 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

\n"; + close FILE; + $going = 0; + } + if ( $line[5] eq 'xcsv' ) { + $line[0] = 'file'; + } + } + + if (($line[0] eq 'file') || ($line[0] eq 'serial')) { + if ($going) { + print FILE "\n"; + close FILE; + } + $id = $line[2]; + if ( $fmts{$id} ) { + $id .= $fmts{$id}++; + } + else { + $fmts{$id} = 1; + } + includef( 'fmt_'.$id ); + open FILE, ">$dir/autogen/fmt_$id.xml"; + print FILE < +
+ $line[4] ($line[2]) +END + print FILE expandoptions($line[1]); + $going = 1; + $dooptions = 1; + if ( defined($line[5]) && ($line[5] ne $line[2]) ) { + print FILE < +This format is derived from the $line[5] +format, so it has all of the same options as that format. + +END + if ($line[5] eq 'xcsv' ) { + $dooptions=0; + } + } + include($id,"formats"); + } + elsif ($going && $dooptions && ($line[0] eq 'option')) { + $nid = 'fmt_'.$id.'_o_'.$line[2]; + print FILE < + $line[2] option + + $line[3]. + +END + include($id.'-'.$line[2],"formats/options"); + print FILE < +END + } +} + +if ($going) { + print FILE "
\n"; + close FILE; + $going = 0; +} + + +open FORMATS, ">$dir/autogen/_filters.xml"; +print FORMATS qq(\n); + +@filters = `./gpsbabel -%1`; + +$going = 0; + +for (@filters) { + chomp; + s/\&/\&/g; + s//\>/g; + @line = split "\t"; + + if ($going && ($line[0] eq 'option')) { + print FILE < + $line[2] option + + $line[3]. + +END + include($line[1].'-'.$line[2],"filters/options"); + print FILE < +END + } + else { + if ($going) { + print FILE "\n"; + close FILE; + } + includef( 'filter_'.$line[0] ); + open FILE, ">$dir/autogen/filter_$line[0].xml"; + print FILE < +
+ $line[1] ($line[0]) +END + include($line[0],"filters"); + $going = $line[0]; + } +} + + +if ($going) { + print FILE "
\n"; + close FILE; + $going = 0; +} +close FORMATS; +close PARTS; diff --git a/xmldoc/old/extract b/xmldoc/old/extract new file mode 100644 index 000000000..9b8424bdc --- /dev/null +++ b/xmldoc/old/extract @@ -0,0 +1,4 @@ +#!/bin/sh + +xsltproc --stringparam id $1 extract.xsl ../readme.xml + diff --git a/xmldoc/old/extract.xsl b/xmldoc/old/extract.xsl new file mode 100644 index 000000000..3a0cfb9f0 --- /dev/null +++ b/xmldoc/old/extract.xsl @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/xmldoc/old/readme.xml b/xmldoc/old/readme.xml new file mode 100644 index 000000000..807f194ef --- /dev/null +++ b/xmldoc/old/readme.xml @@ -0,0 +1,2296 @@ + + + + + + + GPSBabel Documentation + + + + Introduction +
+ The Problem + There are simply too many gratuitously different file formats +to hold waypoint, track, and route information in various programs +used by computers. GPX (http://www.topografix.com/gpx.asp) defines a +standard in XML to contain all the data, but there are too many +programs that don't understand it yet and too much data that are in an +alternate formats. + +
+
+ THE SOLUTION + I needed to convert waypoints between a couple of formats, so I +whipped up a converter and based it on an extensible foundation so +that it was easy to add new formats. Most file formats added so far +have taken under 200 lines of reasonable ISO C so they can be stamped +out pretty trivially. Formats that are ASCII text delimited in some +fixed way can be added with no programming at all via our 'style' +mechanism. + +
+
+ + Getting it and Building it + GPSBabel is distributed in source format that will work on +about any operating system and as ready-to-run binaries for some +operating systems, notably Windows. See the "OS-Specific notes" at +gpsbabel.org for +instructions on those binary kits. + + For operating systems where no binary is provided, you will +have to build it. The code should be compilable on any system with +ISO C89 compilers. It's been tested on UnixWare, OpenServer, OS/X, +Linux, Solaris, and a variety of processors and compilers. + + Libexpat is required for source builds. If you get errors +about expat.h being missing, you must either edit the Makefile to tell +the compiler where it is or install it in a sensible place. Expat can +be downloaded from http://expat.sourceforge.net and is part of Apache so it's very portable. + + + + Usage + + Invocation + Invocation was meant to be flexible. Unfortunately, + that can sometimes lead to unwieldy command lines. + gpsbabel -? + will always show you the supported file types. To use + this program, just tell it what you're reading, where to read + it from, what you're writing, and what to write it to. For + example: + gpsbabel -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx + tells it to read the first file in geocaching.com + format and create a new file in GPX format. + This command will read from a Magellan unit attached + to the first serial port on a Linux system (device names will + vary on other OSes) and write them as a geocaching loc file. + The second command does the same for windows. + gpsbabel -i magellan -f /dev/ttyS0 -o geo -F mag.loc + gpsbabel -i magellan -f com1 -o geo -F mag.loc + Optionally, you may specify "-s" in any command line. This + causes the program to ignore any "short" names that may be + present in the source data format and synthesize one from the + long name. This is particularly useful if you're writing to + a target format that isn't the lowest common denominator but + the source data was written for the lowest common + denominator. I use this for writing data from geocaching.com + to my Magellan so my waypoints have "real" names instead of + the 'GC1234' ones that are optimized for NMEA-only receivers. + A geocacher with a Magellan receiver may thus find commands + like this useful. + gpsbabel -s -i geo -f geocaching.loc -o magellan -F /dev/ttyS0 + gpsbabel -s -i geo -f geocaching.loc -o magellan -F com1 + + + ADVANCED USAGE + Argument are processed in the order they appear on the command +line and are translated internally into a pipeline that data flows +through when executed. Normally one would: + + read from one input + optionally apply filters + write into one output + + but GPSBabel is flexible enough to allow more complicated +operations such as reading from several files (potentially of +different types), applying a filter, reading more data, then write the +merged data to multiple destinations. + + The input file type remains unchanged until a new + -i argument is seen. + Files are read in the order they appear. So you could merge + three input files into one output file with: + gpsbabel -i geo -f 1.loc -f 2.loc -f 3.loc -o geo -F big.loc + You can merge files of different types: + gpsbabel -i geo -f 1.loc -i gpx -f 2.gpx -i pcx 3.pcx \ +-o gpsutil -F big.gps + You can write the same data in different output formats: + gpsbabel -i geo -f 1.loc -o gpx -F 1.gpx -o pcx 1.wpt + If you want to change the character set of input or/and + output side you can do this with the option . You can get a complete list + of supported character sets with "gpsbabel -l". To change + the character set on both sides you should do this: + gpsbabel -i xcsv,style=foo.style -c latin1 -f foo \ + -o xcsv,style=bar.style -c ms-ansi -F bar + Note, that some formats has a fixed character set and ignore this option. + + + ROUTE AND TRACK MODES + Most formats will make reasonable attempt to work + transparently with waypoints, tracks, and routes. Some + formats, like 'garmin' and 'magellan' require the -t flag to work with tracks and + -r to work with + routes. -w is for + waypoints, and is the default. So if you wanted to read all + data from your unit into a gpx file, you might use a command + like: + gpsbabel -t -r -w -i magellan -f com1: -o gpx -F backup.gpx + Tracks and routes are advanced features and don't try + to handle every possible hazard that can be encountered + during a conversion. If you're merging or converting files + of similar limitations, things work very well. + Tracks and routes will sometimes be converted to a + list of waypoints when necessary, f.i. when writing into one + of the CSV formats. The inverse operation is not supported + right now, so reading the converted track back from CSV will + always result in a list of waypoints, not the original track. + + The presence of -s on the command line tends to + creats havoc on tracks and routes since many of these formats + rely on internal linkages between such points and renaming + them may break those linkages. In general, don't use + -s when tracks or + routes are present. + + + + + The Formats +
+ + DeLorme format + + AN1 + This format supports the DeLorme ".an1" drawing file +format. It can currently be used to either read or write drawing +files. If you use this format to create drawing files with routes or +waypoints from another source, it will currently create "Red Flag" +symbols for waypoints, and thick red lines for routes or tracks. It +is possible to merge two drawing layers by doing something like this: + + gpsbabel -i an1 -f one.an1 -f two.an1 -o an1 -F merged.an1 + In this case, the merged data will contain all of the +properties of the original data. + + If your original data contains geocaching-specific +information such as difficulty and terrain, GPSBabel will +automatically include that information in the waypoint descriptions in +the generated drawing file. If you do not want that, specify the +"nogc" option on the command line: + gpsbabel -i gpx -f 12345.gpx -o an1,nogc -F 12345.an1 + The "deficon" option allows you to specify which symbol to +use for points that don't have a symbol already. It defaults to "Red +Flag" but it accepts any symbol name you can put in a DeLorme export +file. To find the name of a specific symbol in Street Atlas, let the +mouse pointer hover over it for a few seconds and the name will be +displayed. + The "color" option allows you to specify the color for +line or mapnote data. It accepts color names of the form "#FF0000" (red) or any +of the color names from the Cascading Style Sheets (CSS) +specification.i + The "wpt_type" option specifies how to represent point data +in the draw file. Valid waypoint types are "marker", "text", "mapnote", +and "circle". The default is "marker". + If the waypoint type is "circle", the "radius" option specifies +the radius of the circles. By default, this is in miles, but it may be +specified in kilometers by adding a 'k'. The default radius is 1/10 mile. + + The "zoom" option specifies at what zoom level Street +Atlas will begin showing reduced versions of your symbols. The default +is 10. Setting zoom to 0 will disable this feature. Setting it to +anything but the default will override the zoom level specified on any +waypoints that were read from an existing an1 file; this is by design. + + GPSBabel has limited experimental support for other types +of layers besides the default "drawing" layer with the use of two +options: + + The "type" option specifies the type of the drawing layer +to be created. The supported values are "drawing", "road", "trail", +"waypoint", or "track". If you do not specify a type, the default +will be either the type of the previous an1 file or "drawing" if there +is no previous file. This lets you merge, for example, two road layers +without having to specify "type=road" for the output. + If you are creating a road layer, you may also use the +"road" option, which allows you to change the types of roads based on +their names. You can change multiple roads at the same time. +Currently supported types are + + + limited +Limited-access freeways + + toll +Limited-access toll highways + + ramp Access +ramps for limited-access highways + + us National +highways (e.g. US routes) + + primary Primary +State/Provincial routes + + state +State/Provincial routes + + major Major +Connectors + + ferry Ferry +Routes + + local Local +Roads + + editable +User-drawn Roads + + + GPSBabel defaults to creating editable roads. These are +routed just like local roads, but may be edited with the drawing tools +in Street Atlas. + This option has a special format that is best +demonstrated by example: + "road=I-599!limited!Beecher St.!major" + + This option will cause any road named "I-599" to become a +limited- access highway and any road named "Beecher St." to become a +major connector. Note that roads that have had their types changed in +this way are not editable in Street Atlas, so make sure they are where +you want them before you change them, and make sure to keep a backup +of your original road layer. Note that the ! is a shell metacharacter +in bash and possibly other shells, so you may have to use single +quotes or some other escape mechanism. + + There is a tutorial how to create an onramp for a limited access highway in Street Atlas USA using GPSBabel. + +
+
+ + Dell Axim Navigation System tracklogs + + axim_gdb + This reads the binary .gpb tracks recorded by Dell Axim. + The structure has a fixed record length with + many unknown bytes, but we can extract the common gps data + we need to create nice tracks in any format. For this reason, + this track format is read-only. + +
+ +
+ + Brauniger IQ series + + BAROIQ + Serial download protocol for the Brauniger IQ series of +barograph recording flight instruments. Creates a track of altitude +vs time which can be merged with a GPS track of the same flight to +create a three dimensional IGC file. +
+
+ + Motorrad Routeplanner 2002 - + + BCR + This file format (extension .bcr) is used in "Motorrad +Routenplaner 2002-..." by Map&Guide. It is a route-onle +format. If you own a newer release (2005...) you can also use the XML +export and convert via gpsbabel ... -i tef +... to your preferred format. May be there are other +products from Map&Guide using the format. + + Coordinates are stored in Mercator format. The +calculation between this and our internal format can result in visible +differences. Experience reports are welcome. + Options: + + - If more then one route are +present in source data, with this option you can determine, which of +this should used for the output. The range is 1 to number routes in +input. If you don't use this, only the first route will be converted. + + + - Not every input format has a real +name for routes in their data. So you can give the route a nice +name. + + - Overwrites the default value of +6371000.0 meters for the earth radius. My be this can help to reduce +differences. + + + Sample BCR command with all options + gpsbabel -r -i gpx -f in.gpx -o bcr,index=1,name="From A to B",radius=6371012 -F a_to_b.bcr + +
+
+ + Cambridge/Winpilot flight analysis and planning software. + + Cambridge + Support for Cambridge/Winpilot flight analysis and planning software for + glider pilots. +
+
+ + Cetus, for Palm OS + + CETUS + Cetus GPS www.cetusgps.dk is a program for +Palm/OS. Working with Ron Parker and Kjeld Jensen, we can now read +and write files for that program. +
+
+ + CompeGPS + + compegps + Suppport for CompeGPS data files. + These data files are "character" separated text files like +the pcx format. "Character" means special data lines can have their +own separator. + Since release 6.1 GPX is also a supported import/export +format for waypoints, routes and tracks. + For more information please have a look at http://www.compegps.com + + Options: + Default Icon name. + Use route/track number +<index> from input data for output. + Give points (waypoints/route +points) a default radius (proximity) + Length of generated short names +(default 16). +
+
+ + CoastalExplorer (tm) + + coastexp + This is the format used by CoastalExplorer (tm). The +format is XML with items uniquely identified by Windows-style UUIDs. +http://www.rosepointnav.com + +
+
+ + CoPilot Flight Planner for Palm OS + + CoPilot + This code is mostly intended to convert CoPilot Flight +Planner for Palmd/OS atabases into other formats. You probably should +not use this to write CoPilot databases, although the code is there, +because GPSBabel doesn't convert magnetic declination values. + Questions, bug reports, etc, to ptomblin at +xcski.com + + http://xcski.com/~ptomblin/CoPilot/ +and http://navaid.com/CoPilot + +
+
+ + cotoGPS, a Palm GPS program + + COTO + Format for cotoGPS, a Palm GPS program. It can read both +track and marker (waypoint) files. It is currently unable to write +track files, so only marker files can be written. The marker +categories are written to and read from the icon description. The 'Not +Assigned' category leaves the icon description empty on read. +Currently geocache info is ignored. + + Options: + + (output) - Name for the Palm 'Not +Assigned' category. Defaults to 'Not Assigned'. + + There is also a debugging option called 'internals' which +takes a XCSV delimiter value. It writes some internal values +(distance, arc, x and y) of the cotoGPS track format to the notes +field. URL: core.de/~coto +Contributed by Tobias Minich. + +
+
+ + CarteSurTable - French shareware + + CST + With this format we can read CarteSurTable data files. +CarteSurTable is a shareware program widely used in France. The data +inside have to be seen as a mixture of a waypoints list, one route and +several tracks. phgiraud.free.fr + +
+
+ + Comma Separated Variable, for Delorme S&A +Deluxe + + CSV + There are a billion variants of Comma Separated Value +data. This is the one that makes Delorme S&A Deluxe 9 happy. It's +also a very simple program and useful for many other programs like +spreadsheets. + CSV is also the correct format for Lowrance MapCreate, +their commercial mapping program, or GDM6 (their free waypoint +manager) for iFinder which is available at lowrance.com + +
+
+ + Plain CSV + + custom + This is a "kitchen sink" CSV format. No known program +will read it, but it's handy for simply converting an arbitrary file +to text so it can be pulled into a spreadsheet or manipulated with +text processing tools. +
+
+ + Nivitrak DNA marker format + + DNA + Navitrak DNA marker format - Another CSV format file. This +is the format that is compatible with the DNA Desktop import/export +command. Reading the binary Markers.jwp format directly off the data +card is not supported yet. Contributed by Tim Zickus. +
+
+ + EasyGPS binary format + + EasyGPS + This is the binary file format used by EasyGPS. This +format is seemingly being phased out in favor of GPX in newer versions +of EasyGPS, but this allows conversions to and from the old binary +.loc format. + + + http://www.easygps.com/ + + Information about and sketchy code to implement this file +format were provided by Eric Cloninger. + +
+
+ + Fugawi CSV format + + Fugawi + This was a requested CSV format, *not* the proprietary +binary format used by Fugawi. Like any other CSV format, GPSBabel +cannot read tracks in this format, but converting a track into it and +then importing as track in Fugawi works. + It is known to work with Fugawi V3.1.4.635. When +importing/exporting waypoints, one has to specify the order of fields +as follows (names of fields may depend on the language used by +Fugawi): + + - Name + - Comment + - Description + - Latidude + - Longitude + - Altitude (metres) + - Date (yyyymmdd/yymmdd) + - Time of day (hhmmss) + + When importing tracks, use "[ignore]" instead of "Name", +"Comment" and "Description". + + http://www.fugawi.com/ + +
+
+ + Garmin waypoint format + + GARMIN + Waypoint serial upload and download works reliably under +both POSIX and Windows. I originally tested it with a Vista, a V, and +a base eTrex, all graciously provided on loan by Joe Armstrong, but +it's now regularly exercised on a 60CS (USB and serial) and many other +models. The communications library used, jeeps, claims to support +most models of Garmin hardware. Be sure the GPS is set for "Garmin +mode" in setup and that nothing else (PDA hotsync programs, gpsd, +getty, pppd, etc.) is using the serial port. + + GPSBabel supports the USB Garmins under Windows and on +Linux and OS/X via libusb. It's reported successful with VistaC, +SummitC, 60C, 60CS, 76C, 76CS, 96C, and Quest. Some users report +success with StreetPilot 2610 and some do not, but nobody's followed +up with details on that. + + Currently, only a single USB unit at a time can be +supported. The device name to use on the command line is "usb:" Thus, +to read the waypoints from a Garmin USB unit and write them to a GPX +file: + + gpsbabel -i garmin -f usb: -o gpx -F blah.gpx + When reporting problems with Garmin, be sure to include +the full unit model, firmware version, and be prepared to offer +debugging dumps by adding "-D9" to the command line, like: + + gpsbabel -D9 -i garmin -f usb: -o gpx -F blah.gpx + Custom icons are supported on units that support that. +Neither GPSBabel nor your firmware know what is associated with any +given slot number. They don't know that the picture you placed in the +first slot is a happy face, they only know they're in the lowest +numbered slot. GPSBabel names the them consistently with Mapsource, +so they are named 'Custom 0' through 'Custom 23'. + +
+ +
+ + Garmin POI Database. + + garmin_poi + The Garmin POI loader +loads custom points of interest into certain models of +Garmin GPS receivers. (As of this writing, only the models introduced +in 2005 and later are supported. See Garmin's site for more info.) +This is the format readable that that program. +
+ +
+ + Garmin MapSource Text Export (tab delimited). + + garmin_txt + + garmin_txt is a format that contains nearly all information as in the MapSource main format, GDB. +garmin_txt has some computed values like distances between routepoints and trackpoints, speed, and course (heading) in addition to the standard data fields. + + +The main goal of garmin_txt is to make aviation data more available. Because +MapSource supports only the export, GPSBabel gives you the possibility to +bring aviation data into MapSource. + + +During the export with MapSource, some fields are written using local settings +of MapSource and Windows. These include grid format, gps datum, distance and +temperature units, and the representation of date and time fields. GPSBabel +tries to read all items automatically. Problems with date and time format can +be solved with the options 'date' and 'time'. + + Options: + - input/output date format (Windows-like. For example "YYYY/MM/DD") + - write coodinates using this (GPSBabel known!) datum + - output unit for distance values, M (=metric, m/km/kph) or S (=statue, ft/mi/mph) + - write coordinates with precision # (# numbers behind dot) + - output unit for temperature values, C (=celsius) or F (=fahrenheit) + - input/output time format (Windows-like For example, "hh:mm:ss xx") + - write timestamps x hours relative to UTC + + Command showing garmin_txt output with all options + gpsbabel -i garmin_txt,date="MM/DD/YYYY",time="hh:mm:ss xx" \ + -f in.txt \ + -o garmin_txt,date="DD.MM.YYYY",datum="WGS 72",dist=m,prec=6,temp=c,time="HH:mm:ss",utc=+2 \ + -F out.txt + + +
+ +
+ Garmin 301 data. + garmin301 This is a very simple format that +is most useful for exporting data from a Garmin301 to other programs +for analysis. It's a simple comma delimited format that includes the +timestamp, 3D position information and heart rate so you can pull it +into a spreadsheet or graphing program. +
+ +
+ + GeocachingDB format + + Gcdb + This is the GeocachingDB by DougsBrat. It works with v2 +and v3 of this program. See vip.hyperusa.com + +
+
+ + Garmin GPS Database (as in MapSource) +format + + GDB + Support for the "Garmin GPS Database" format used by +default in MapSource versions since release 6.0. By default we create +gdb's of version 2. Version 2 is used in Mapsource 6.3 and 6.5. + + Garmin GPS database is an undocumented file format. The +basic info for this module comes from the existing MapSource +conversion code. + + Additional options: + + - set the data format version of the +output file (currently 1 or 2); 2 is our default. + + - Drop hidden route points (means +calculated stuff) + + - default category on output +(1..16) +
+
+ + geocaching.com .loc file format + + GEO + geocaching.com spits up geocaching.loc files that are +XML-ish but not quite GPX. Becuase it's so close to GPX, this format +is very well supported. +
+
+ + GeocachingDB PDA format + + Geocaching DB + This is a PDA file format. It was tested against version +2 of GeocachingDB and a development snapshot of version 3. Information +on the file format came from Dougs Brat and Ron Parker. A +particularly handy way to use GPSBabel on these files is to use +GPSBabel to read a GPX file with Groundspeak (geocaching.com) +extensions and let it write you a GeocachingDB file that contains the +cache names, difficulty, terrain, and such. + + vip.hyperusa.com + +
+
+ + GEOnet Names Server country file format +(input) + + GEOnet + Input support for the GEOnet Names Server (GNS) country +file structure. Export to this format is not possible, as this format +has too many fields that we never get populated by any other +format. +
+
+ + Geoniche - Palm format for off-road users + + geoniche + Geoniche is a Palm/OS application oriented for the +off-road user. This module was contributed by Rick Richardson. See +nwlink.com + +
+
+ + Garmin logbook format for Forerunner and +ForeTrex + + glogbook + This is the XML format used by the Garmin Logbook product +that ships with Forerunner and Foretrex. http://www.garmin.com + +
+
+ + Google maps routes + + GOOGLE + This format is designed to read the XML emitted when you +tack "&output=js" onto the end of a Google Maps route URL (use +the "link to this page" option to get a usable URL.) This allows you +to plan a route using Google Maps, then download it and use it in your +own mapping program or GPS receiver. If you use a Unix-compatible +operating system, this shell script might be useful: + + +#!/bin/sh +FROM="233 S. Upper Wacker Dr, Chicago, IL" +TO="1060 W. Addison St, Chicago, IL" +wget -O - "http://maps.google.com/maps?q=$FROM to $TO&output=js" \ +2&>/dev/null >google_map.js +gpsbabel -i google -f google_map.js -o gpx -F google_map.gpx + + Note that Internet Explorer has been observed to damage +the XHTML beyond recognition so use a better browser to save the pages +such as Firefox or Mozilla. + +
+
+ + Palm OS format for GPilots + + GpilotS + This is a Palm/OS file format for GPilotS. It was tested +against version 6.2. + + + http://www.cru.fr/perso/cc/GPilotS/ + + Neither tracks nor routes are supported at this +time. +
+
+ + Delorme gpl format + + gpl + This is the 'gpl' format as used in Delorme mapping +products. It is a track format and contains little more than the +tracklog of a GPS that was attached while driving. frontiernet.net + +
+
+ + GpsDrive way.txt file format. + + GPSDRIVE + GpsDrive way.txt file format. A space seperated format +file. Tested against GpsDrive v 1.30 found at kraftvoll.at. +Contributed by Alan Curry. +
+
+ + GpsDrive saved track format + + GPSDRIVETRACK + Format used by GpsDrive to save tracks. Like GPSDRIVE a +space seperated format file. See above for a link to GpsDrive. +Contributed by Tobias Minich. +
+
+ + GPS Manager format (WGS84, DDD) + + GPSMAN + GPS Manager can read and write formats that this +converter doesn't understand. The default formats (WGS84, DDD) work +reliably. +
+
+ + GPSPILOT file format + + GPSPILOT + The file format for GPSPILOT gpspilot.com was provided by Ron +Parker. The output from this module has been tested with GPSPilot +Tracker v5.05sx, but it is based on reverse-engineering so it may not +work with all versions of all GPSPilot products. It had read-only +support for Airport, Navaid, City and Landmark files but will read and +write Point files. +
+
+ + GPSUtil file format + + GPSUTIL + GPSUtil has a simple file format of this program that runs +on POSIX- compliant OSes like UNIX and Linux. Reads and writes of +this format are reliable. (I've also contributed to this program.) +It's available at cs.uakron.edu. +
+
+ + EasyGPS, ExpertGPS etc format. + + GPX + This is the most capable and expressive of all the file +formats supplied. It is described at topografix.com and is +supported by EasyGPS, ExpertGPS, and many other programs described at +topografix.com + +
+
+ + GPS TrackMaker format. + + GTM + Input and output support for waypoints, tracks and routes in + the GPS TrackMaker + binary format. + Code implemented by Gustavo Niemeyer. +
+
+ + Mac OS HikeTech formats. TopoDraw, Link2GPS & +GPSWrite + + Hiketech + This is the .gps format used by the Mac OS X applications +written by HikeTech. These include TopoDraw, Link2GPS, and GPSWrite. +More information about these products can be found at hiketech.com + +
+
+ + Holux format (Holuxgm-100) + + HOLUX + The Holuxgm-100 (e-fox) gps receiver uses standard +compact flash cards. File formats were provided by Holux-Taiwan +holux.com to the author. +The code was tested against version 2.27E1; other versions and +receivers may work but have not been explictly tested. Anyone with +information on other Holux receivers is encouraged to contact +jochen@bauerbahn.net. + + When copying the .wpo file to a flash card, the file must +be named tempwprt.wpo as the +receiver will ignore all other files. + + Comparing the waypoints of a .wpo files against other +formats like .gpx you may notice a small difference in the latitude +and longitude values. The reason is the low resolution of the +coordinates in the wpo file format. In a .wpo file the reolution is +1/10"; in gpx for example it is 1/100". A a practical matter, this +loss is only about 1.7 meters (5 feet). + + The generated waypoint failes can also be used by MapShow +version 1.14. This program is free of charge from the Holux web site. + + This format was contributed by Jochen Becker. + +
+
+ + HSA Systems Endeavour Navigator format + + hsandv + HSA Systems Endeavour Navigator format - will import both +the old version 4.x binary files, and the newer XML based ones. Only +writes the new XML (5.0 and above) format. (use the .exp +extension) +
+
+ + HTML format + + HTML + HTML output generates a single HTML file of all of the +waypoints in the input file. It supports a number of Geocaching GPX +extensions, as well as filters out potentially harmful HTML from the +input file while maintaining almost all of the source HTML formatting. +Use the 'stylesheet' option to specify a CSS stylesheet to be used +with the resulting HTML file. Use the 'encrypt' option to encrypt +hints from Groundspeak GPX files. Use the 'logs' option to include +Groundspeak cache logs. + + The following command line reads a GPX file with +Groundspeak extensions and writes an HTML file with encrypted hints +that is rendered using a custom stylesheet: + + gpsbabel -i gpx -f 12345.gpx \ + -o html,stylesheet=green.css,encrypt -F 12345.html + +
+
+ + FAI/IGC Data file format + + IGC + FAI/IGC Data File -- Used by the international gliding +community to record gliding flights. IGC files can be converted to +and from tracks representing recorded flights, and routes representing +task declarations in other formats. +
+
+ + IGN Rando track file format + + IGNRando + Input and output support for IGN Rando track files. IGN +Rando is a program mainly used in France for Topo maps. The files are +XML based and are "windows-1252" encoded. Trackpoints come without +timestamp. + + Options: + + + - Use track number <index> +from input data for output. The range is 1 to number of tracks in +input. + +
+
+ + Keyhole Markup Language format. + + KML + KML, the Keyhole Markup Language, is used by Keyhole and +Google Earth. (Google Earth uses GPSBabel internally for receiver +communications and several file format imports and exports. There are +features in this file format that we don't support such as camera +views, but waypoints, tracks, and routes work well. + Additional options: + + (default n=1) Draws lines between +points in tracks and routes when n is non-zero. + + (default n=1) Draws placemarks +for tracks and routes when n is non-zero. + + (default n=6) Width of drawn +lines, in pixels. + + (default=65eeee17) Line +colour specified in hex AABBGGRR. + + (default n=0) Altitudes are +not clamped to ground when n is non-zero. This option is more useful +to pilots than to hikers. +
+
+ + Kartex 5 waypoint + + kwf2 + Support for Kartex 5 waypoint files. Kartex is a Swedish + map and GPS positioning system. GPSBabel can read and write + files from Kartex 4 and 5 with WGS84 coordinates. UTM or + Swedish grid are not supported. + +
+
+ + Kartex 5 trackfiles + + ktf2 + Support for Kartex 5 trackfiles. For more info see kwf2. +
+
+ + Lowrance iFinder .USR format + + LowranceUSR + The Lowrance iFinder GPS series has the unique capability +to output its data to an MMC card. The data is saved to the card as a +.USR file and can be read by your computer using a card reader. +Waypoints, routes, tracks are supported. By default, Event marker +icons are converted to waypoints. Symbols tend to get lost in the +translation. + Additional options: ignoreicons - don't convert icons to +waypoints merge - (USR output) merge all tracks into a single track +with segments break - (USR input) break track segments into separate +tracks +
+
+ + Palm OS for Map & Guide format + + mag_pdb + With this format we support the Palm/OS export for +Map&Guide based products like "PowerRoute", +"Motorrad-Routenplaner" and (maybe) other software. The exported files +can contain maps and/or route descriptions. The reader for this format +has been tested with PowerRoute 5+6, Motorrad-Routenplaner +2002(-2006). +
+
+ + Magellan format + + MAGELLAN + Waypoint serial upload and download works reliably to the +315, 330, Meridian, and SportTrak family. I expect it to work on any +modern Magellan unit. + As of 08/30/02, GPSBabel can also read and write the +files that can be stuck on the SD memory cards with the Meridian +models. Simply specify a file instead of a serial port. + Communication errors are handled robustly and +verification of data is enabled. + Additional suboptions: baud: may be 1200, 2400, 4800, 9600, +19200, but must match receiver. +
+
+ + Magellan Explorist format + + MAGELLANX + The SD card format used by the Magellan Explorist 400, +500, and 600. It's identical to the Magellan SD format used by +Meridian, but allows longer waypoint names. + You should name any file created with this format with a +".upt" extension so the firmware can read it. +
+
+ + Magellan SD card format + + MAGGEO + The SD card format used by the Magellan Explorist 400, +500, and 600 to describe geocaches. Notice what while the format can +hold an infinite number of geocaches, the unit will read and silently +discard all but 200 geocache POIs at a time. + You should name any file created with this format with a +".gs" extension so the firmware can read it. + +
+
+ + Magellan Nav Companion format + + MAGNAV + Magellan NAV Companion for Palm/OS is not really designed +for this sort of use, but its file format is supported and with a +little bit of patience you can both read and write NAV Companion +waypoints. Please read README.magnav for further tips on getting +waypoints in and out of NAV Companion. This conversion is based on +partially incomplete reverse-engineering of the record format, so it +may not work with all versions of NAV Companion. It has been tested +with version 2.10 and 3.20. +
+
+ + Mapconverter format from Mapopolis + + mapconverter + Mapconverter is a format this is read by Mapopolis.com's +mapconverter application. Full details of it's usage are available in +the file README.mapconverter. +
+
+ + Magellan Mapsend format + + MAPSEND + Magellan was smart enough to document their file format to +make creating software like this possible. + Additional options: + + - set the MapSend version to generate TRK files, +since new MapSend versions can't open V3 files. Options are 3 (MapSend v3.0) or +4 (MapSend v4.0 and v4.1). + +
+
+ + Garmin Mapsource format + + MAPSOURCE + Garmin Mapsource format appears compatible with the +various members of that product family. Icon mapping is attempted +between different MapSource versions. Altitude is supported, but +proximity and depth are not. Naming files *.mps will allow +file->open in Mapsource to find the files more easily. Versions 3, +4 and 5 of the Mapsource data format are handled automatically on +input and by default the output is version 5. (Until 3/2004, it was +version 3, but since Mapsource updates are free, the convenience of +having modern icon sets outweighs the backward compatibility concern. +Users of other versions can either upgrade or specify the switches to +get get output in a compatible format.) Waypoints, routes and +tracklogs are all handled, but maps sets are ignored. + + Information on the Garmin Mapsource format was provided +by Ian Cowley and Mark Bradley. The code was implemented by Robert +Lipe and Mark Bradley. + Additional options: + + - set the length of generated +shortnames + + - set the data format version +of the output file (3,4 or 5) + + - if the output file already +exists, then the output is merged with it. This allows MapSource +sections not being handled to remain intact (e.g. map sets) +
+
+ + Microsoft Autoroute 2002-2006 reader + Microsoft Streets and Trips reader + + MSroute + Input support for Microsoft AutoRoute 2002-2006 .axe files +and Microsoft Streets and Trips .est files. +These files contains only routes. We can extract the coordinates and +the names of the points within route. An export to this format will +not be supported. + Only the start, stops, and end points are stored in the +.est/.axe/.ptm files. Turn-by-turn route data is not stored in the +.est/.axe/.ptm files, and is recalculated by the Microsoft title each +time on opening the file. This means that the output of GPSBabel will +not contain turns needed for driving directions. + One possible approach to achieve similar results is to +use the Streets and Trips drawing tools to trace a line over the +interesting parts of the route to capture intersections or key turns. +GPSBabel will capture stops in the route and insert those as turns, so +adding stops at intersections can also improve the results when converting. + +
+
+ + Maptech Exchange format. + + MXF + Maptech Exchange Format - Another CSV format file. This +format complies with (at least) Maptech Terrain Navigator, Terrain +Professional, Take a Hike, and ExpertGPS import/export MFX. +Contributed by Alex Mottram. +
+ +
+ + NetStumbler CSV summary file format + + Netstumbler + NetStumbler 0.4 Summary File -- Another CSV format file. +The default behavior when creating waypoints is to use the SSID for +the short name, and information about the access point for the +description. When the SSID is not unique, is not available, or +consists of whitespace, a shortname is synthesized. The snmac option +uses the MAC address for the shortname, and includes the unmodified +SSID in the description. Different icons are assigned to encrypted, +non-encrypted, stealth, and non-stealth access points; these may be +changed with options. Import only. + +This format also works with MacStumbler. + Additional options: + + - Name of icon used for +non-stealth non-encrypted access points + + - Name of icon used for stealth +encrypted access points + + - Name of icon used for stealth +non-encrypted access points + + - Always use the MAC address as the +shortname. +
+
+ + National Imagery and Mapping agency +format + + NIMA + This is a CSV format from the National Imagery and Mapping +Agency. +
+
+ + NMEA0183 log and waypoint format + + nmea + This format is the file representation of the NMEA0183 +log and waypoint format. Representative programs include: + + genimap.fi + + + homepages.tig.com.au + + + gpstm.com + + + gpsmaster.nl + + + silcom.com/~rwhately + + + visualgps.net + + + gpsu.co.uk + + + kolumbus.fi + + + commlinkx.com + +
+
+ + Navigon Mobile Navigator route (.rte) +files. + + nmn4 + Support for Navigon Mobile Navigator route (.rte) files. +This is a very simple text format that only requires coordinates, but +has fields for many other things. We only write coordinates as fields +like 'city' and 'street' cannot typically be populated from other +formats. www.navigon.com + +
+
+ + Tab seperated file format - numerical +processing + + OPENOFFICE + Tab seperated export-all (except geocaching data) file +format. Intended to serve as source for number-processing +applications like OpenOffice, Ploticus and others. Tab was chosen as +delimiter because it is a) supported by both OpenOffice and Ploticus +and b) is not ',', so you can use sed -i +"s/./,/g" <x>.csv' to adapt it to locales where ',' is +used as decimal seperator. Contributed by Tobias Minich. +
+
+ + OziExplorer Waypoint Format + + OZI + OziExplorer Waypoint Format - Another CSV format file. +Tested against OziExplorer v 3.90.3a / Shareware. Contributed by Alex +Mottram +
+
+ + PalmDoc output format + + PALMDOC + PalmDoc output is similar to Text output, except that it +generates a Palm Database (PDB) file suitable for use with programs +like CSpotRun, TealDoc, AportisDoc, Palm Reader, and others. The +resulting file also contains bookmarks to make it easy to jump to a +particular waypoint. To suppress the dashed lines between waypoints, +use the 'nosep' option. To specify a name for the document, use the +'dbname' option. Use the 'encrypt' option to encrypt hints from +Groundspeak GPX files. Use the 'logs' option to include Groundspeak +cache logs. If you would like the generated bookmarks to start with +the short name for the waypoint, specify the 'bookmarks_short' option. +This is particularly useful when used in combination with the 'sort' +filter. + + The following command line reads a GPX file with +Groundspeak extensions and writes a Palm document with encrypted hints +and logs: + + gpsbabel -i gpx -f 12345.gpx \ -o + "palmdoc,dbname=Unfound Geocaches,encrypt,logs" \ + -F 12345.pdb + +
+
+ + PathAway for Palm file format + + PathAway + PathAway is a Palm software designed for handling "most" +GPS devices (including BlueTooth). In this time (I mean 2005) a free +tool to convert this database is located on the homepage of PathAway +(www.pathaway.com). But I've read there ... for windows and the output +formats are also very limited. + +
+
+ + Garmin PCX format + + PCX + Garmin documents only PCX5, an older format limited to +the lame NMEA six-character waypoint names that's treated as a +second-class citizien in current versions of MapSource. In Mapsource, +use file->import to read these files. If you name the files *.wpt, +Mapsource will find them easier. + + In general, you should prefer the "mapsource" file format +to this one. + +
+
+ + KuData's Psion PDA format + + PsiTrex + This is a text format created by KuDaTa's PsiTrex program +for the Psion PDAs. The format can't be readily handled by XCSV, so +this format is handled explicitly. Waypoints, routes and tracks are +all handled, with icon names used corresponding to verison 1.13 of +PsiTrex. This module was contributed to GPSBabel by Mark +Bradley. +
+
+ + Microsoft PocketStrees 2002 pushpin +format + + PSP + Microsoft's PocketStreets 2002 Pushpin (.PSP) format is +not yet completely documented. THE .PSP MODULE DOES NOT WORK WITH MS +STREETS & TRIPS 2002 .EST FILES. To create .PSP files from +Streets & Trips 2002, you will need to have PocketStreets support +installed. + + Please note that MS Streets & Trips only *EXPORTS* +.PSP files. It does not import them. MS Streets & Trips 2002 only +imports CSV files. To use .PSP files, simply copy them over to the +same folder on the mobile device as the map (.MPS), and open +PocketStreets. It should also be noted that in the case a pushpin is +outside of the exported map area, the pin will be "grayed-out" and +unused in PocketStreets. This is a good thing as it allows us to +create one big .PSP file that covers multiple .MPS files. +Unfortunately, you need one .PSP file for every .MPS file. :( +
+
+ + QuoVadis for Palm OS format + + QUOVADIS + QuoVadis for Palm OS marcosoft.com is a program for +Palm/OS. Working with record definitions provided by MarcoSoft and +further experimentation by Bruce Thompson and "Fuzzy" from the +Geocaching Forums to nail down the format precisely. + Should work fine for import and export. + One thing of note, QuoVadis stores all waypoints in a +single Palm Database without using categories. This means that it may +be difficult to keep personal waypoints separate from generated +waypoints. What Bruce recommends is taking the QuoVadisMarkerDB.PDB +file synced down from your Palm Powered device and extract the +waypoints you personally set to a GPX file. Then using GPSBabel's +joining capabilities generate a new PDB file from the personal file +and the other waypoint files of interest. + Currently the selection of icons to display and the scale +at which to display them is hardcoded. Also there is no support for +notes associated with waypoints. This will be addressed in a future +revision. +
+
+ + Microsoft Streets and Trips import format + + s_and_t + This is a format for importing into Microsoft Streets and +Trips. It's been exercised on versions 2003, 2004, and 2005. Detailed +instructions on how to use it, including preserving hyperlinks, are at +gpsbabel.org + +
+
+ + Street Atlas USA 2004 Plus format + + saplus + This format is for Street Atlas USA 2004 Plus. + + For geocachers importing data from a tool like GSAK or +Spinner, import the file twice in XData. One will create a file with +the Cache description as a hyperlink on the flag. This can clutter up +the screen and when you try to zoom in, it causes problems. So the +second one will only have a flag. Thus you can turn off and on which +one you want to view. The first time you import the file, in the +assign field types, check the circle above Full Name and then next. +The second time you import the file do not check any circle and in the +second to last column, change URL to none and then click next. Use the +same name you used the first time but add -Flag to it. + +
+
+ + Delorme (anr, rte, rtd files) + + saroute + This is a catch-all used by many Delorme mapping products +and reads the anr, rte, and rtd formats as either tracks or +routes. + The 'turns_only' option causes GPSBabel to read only the +waypoints associated with named turns. This should create a list of +waypoints that correspond to the itinerary from Street Atlas. + The 'turns_important' option only makes sense in +conjunction with the 'simplify' filter. It ensures that the route +simplification process will remove the points corresponding to turns +only after it has removed all other route points. + + The 'split' option causes GPSBabel to create separate +routes for each street, creating a new route at each turn point. For +obvious reasons, 'split' cannot be used at the same time as the +'turns_only' or 'turns_important' options. + The 'controls' option lets you read the control points +(start, end, vias, and stops) for your route as well as the route +itself. The default for this option is 'none', which won't read the +control points. You may also specify 'waypoints', which reads the +control points as waypoints, or 'route', which creates an extra route +named 'control points' containing just the control points in order. +Note that if your goal is to create an arc or other CSV file, you +should use 'none' (or not use this option, which is the same +thing.) + The 'times' option causes GPSBabel to read the route as if +it were a track, synthesizing times starting from the current time, using +the estimated travel times specified in your route file (you can change your +travel speeds in the DeLorme product you used to create the route file.) + All options only apply to route files from newer (anr) +versions of DeLorme software; older versions didn't store the turn +information with the route. + +
+
+ + SeeYou flight analysis and planning software. + + SeeYou + Support for SeeYou flight analysis and planning software for + glider pilots. Tasks, runway info, and most other data specific + for glider pilots is not preserved, but this is a convenient way + to get your flight data in other programs. www.seeyou.ws +
+
+ + Suunto Trek Manager WaypointPlus format. + + STMwpp + Support for Suunto Trek Manager (STM) WaypointPlus +format.. Simple structure with coordinates and timestamp. Route +points (waypoints) have additionaly shortname. The files can only +contain one route or one track. www.suunto.fi + + + Options: + + + - Use route/track number +<index> from input data for output. + +
+
+ + Unix tab seperated file format + + tabsep + Dumps all fields in a traditional Unix tab separated +style. +
+
+ + TourExchangeFormat. for Map&Guide + + TEF + TEF, internal called "TourExchangeFormat", is a XML based +export format, used by Map&Guide "Motorrad-Routenplaner 2005/06". +Another posibility to exchange data with this are the .bcr files, +which are supported by GPSbabel in both directions (see BCR). + + Via XML this software can only export routing data. So we +don't support writing. With the option "routevia" you can eliminate +calculated route points from tef source file. + gpsbabel -r -i tef,routevia -f in.xml -o gpx -F out.gpx +
+
+ + Plain text, for people + + TEXT + This is a simple human readable version of the data file, +handy for listings of any type of waypoint files. Use the 'nosep' +option to suppress the lines of dashes between entries. Use the +'encrypt' option to encrypt hints from Groundspeak GPX files. Use the +'logs' option to include Groundspeak cache logs. + + The following command line reads a GPX file with +Groundspeak extensions and writes a text file with encrypted hints: + + gpsbabel -i gpx -f 12345.gpx -o text,encrypt -F 12345.txt + +
+
+ + US Census Bureau mapping format + + TIGER + The U.S. Census Bureau provides online mapping facilities. +This format is described at: tiger.census.gov. +Do notice that this format is not the actual Tiger line mapping +records, but rather the interface to their online mapping +program. +
+
+ + TopoMapPro places file + + TMPRO + TopoMapPro Places File. Reads and writes places files for +use in TopoMapPro topomappro.com). As this file +type can store links other than web links, anything that is not a http +url will be discarded. Note that this does not do datum conversions, +so if your input file does not have WGS84/NZGD2000 data, your output +file won't either. Colour of waypoint icons defaults to red. +
+
+ + TomTom .ov2 POI files + + TomTom + This format can read and write TomTom .ov2 (POI) files, +as used by the TomTom GO and TomTom Navigator. It has been tested +with an original TomTom GO running version 5.00 of the TomTom +software. There may be some records that confuse the input module - +if you have an example of such a record "in the wild", and you aren't +restricted from sharing it, we encourage you to post to the +gpsbabel-misc mailing list to contact a developer. + Note that in addition to the .ov2 file, you will need a +.bmp file for the icon. It should be 22x22 and 16 colors, and have +the same name (not including the extension) as the .ov2 file. + +
+
+ + National Geographic Topo Waypoint format. + + TPG + National Geographic Topo! Waypoint and Route Format. This module +reads and writes .TPG files created by various editions of NG Topo! +Reading/writing of route data is not supported yet. +Contributed by Alex Mottram. + The option 'datum="datum name"' can be used to override +the default of NAD27 ("N. America 1927 mean") which is correct for the +continental U.S. Points in Hawaii should use "Old +Hawaiian_mean" + Contributed by Alex Mottram. +
+
+ + National Geographic Topo! Track Format. + + TPO + This module reads .TPO files created by various editions +of NG Topo!. For version 2.x files it will only read tracks. For +version 3.x files it will read Tracks/Routes/Waypoints/Map +Notes/Symbols/Text Notes. The latter three are converted to +waypoints. + 2.x support contributed by Steve Chamberlin. 3.x support +contributed by Curt Mills. + +
+
+ + Universal csv with field structure in first line. + + unicsv + + Unicsv examines the first line of a file to determine the field + order and field separator in that file. It is thus read-only format. + + + If the first line contains any tabs, the data lines are assumed + to be tab separated. Otherwise the fields are assumed to be + separated by commas. + + + The list of keywords include "lat", "lon", "desc", "name", + "notes", "alt", "urm z", "utm n", "utm e", and "url". + Fuller spellings (i.e. "longitude") may be used. + + + A typical file may be: + + Name, Latitude, Longitude, Description + GCEBB,35.972033,-87.134700,Mountain Bike Heaven by susy1313 + GC1A37,36.090683,-86.679550,The Troll by a182pilot & Family + + +
+
+ + vCard format for Apple iPod etc. + + vCARD + The vCard output is intended to be in a format that +enables waypoints to be viewed with an Apple iPod. This is achieved by +mapping waypoint fields into vCard fields that can be displayed as +'Contacts' on the iPod. With the iPod mounted as a hard disk (see your +iPod manual for instructions), the resulting VCF file should be moved +into the iPod 'Contacts' folder. As an alternative, Mac OS X users may +prefer to drag the VCF file into their address book and synchronize +with the iPod using iSync. By default hints are unencrypted; use the +'encrypt' option to encrypt the hints. +
+
+ + Vito Navigator II format + + VitoSMT + Vito Navigator II is a Pocket PC GPS application. This +format reads a Vito Navigator II .SMT track file and can work in +either waypoint or track mode. The speed, heading and Dilution of +Position data is written in the notes field. + Support for writing .SMT tracks is very experimental and +may crash VitoNavigator II on the Pocket PC. +
+
+ + Aspecto Software's WiFiFoFum + + wfff + WFFF is the export format for Aspecto Software's WiFiFoFum 2.0 for Windows Mobile PCs. + It is a simple XML format that is read-only to GPSBabel and stores information about a WiFi stumbling session. + All WiFi-specific elements are written in the description field, similar to the netstumbler format. +
+
+ + For user supplied style files + + XCSV + XCSV is an open-ended "Whatever Separated Values" parser +/ writer designed to work with user-supplied "style" files. It should +handle at least a few thousand of the billion CSV variants available. +By itself, it doesn't comply to any format, however *most* CSV +variants can be described as a "style" and fine-tuned by the end user. +For more information on it's use, please see README.style in the +style/ sub-directory of GPSBabel. +For an example of using the XCSV module within your C program, look at +the ozi.c, mxf.c, and xmapwpt.c sources in the GPSBabel +directory. This module was contributed to GPSBabel by Alex +Mottram. + Additional Options: + + - **REQUIRED** Path to +XCSV style file. + + - Maximum length of +synthesized shortnames. + + - Switch defining +whether or not to allow whitespace in synthesized shortnames. (0 = NO +WHITESPACE, 1 = WHITESPACE OK). + + - Switch defining +whether or not to force uppercase in shortnames. (0 = LEAVE AS IS, 1 += UPPERCASE ALL). NOTE: sn* options require use of the '-s' command +line option. + + xcsv Command options + gpsbabel -i xcsv,style=foo.style -f foo \ + -o xcsv,style=bar.style \ + -F bar + + gpsbabel -s -i gpx -f foo.gpx \ +-o xcsv,style=my.style,snlen=8 -F bar + +
+
+ + Delorme TopoUSA/XMap Conduit format + + XMap + Delorme TopoUSA/XMap Conduit is one of the billion CSV +variants mentioned above. It's just like S&A with the addition of +a completely pointless line at the beginning and end of the file. This +is the format used to hot-sync to XMap from withing TopoUSA. Done with +help of Dan Edwards. +
+
+ + + Delorme XMap/Street Atlas 2006 Handheld Conduit format + + + XMap2006 + Delorme XMap2006 Conduit is just like XMap, except there are + no spaces between fields and the coordinate format is slightly + different. The completely pointless header and footer lines + are the same, at least. Use this to create the XMapHHWptsSend.txt + file needed to sync to Street Atlas Handheld 2006. + Note that in order to keep from creating duplicates on your handheld, you must first remove the file "XMapWptsDB" from your handheld, restart SAHH2006 on the handheld to create an empty database, and THEN sync the new file. +
+
+ + Delorme XMapHandHeld street Atlas format. + + XMapWpt + Delorme XMapHandHeld Street Atlas USA is another of the +billion CSV variants. This is the format used by XmapHH SA USA on (at +least) PocketPC O/S. Please see README.xmapwpt for more information +on it's intricacies. This XMap is not to be confused with the XMap +mentioned above. Contributed to GPSBabel by Alex Mottram. +
+
+ + DATA FILTERS + GPSBabel supports data filtering. Data filters are + invoked from the command line via the '-x' option. It should be + noted that data filters are invoked in the internal pipeline at + the point that corresponds to their position on the + command. This implies that specifying a filter before reading + any data ('-x <filter> -f <file>'), despite being + legal, will not have any effect. The advantage is that filters + can be used intermittently between several variations of input + and output functions. It should also be noted that filtering + data from different input types can sometimes produce + undesirable results due to differences in the native data + formats. + + Beware that most filters only apply to a certain kind of + data. This is usually indicated below by referring to points, + tracks or routes in the first sentence which describes each + filter or in the table at gpsbabel.org + . + +
+ POSITION + The position filter is designed to remove points based + on their proximity to each other. Distances can be passed on + the command line by passing the distance=XXX option to the + filter. Distance options may be expressed in feet + (distance=3f) or + meters (distance=1m). + The default is zero feet, essentially a duplicate position. + + + Using position filter to suppress close points + gpsbabel -i geo -f 1.loc -f 2.loc -x position,distance=1f \ + -o mapsend -F 3.wpt + + would remove multiple points that are within 1 foot of + each other, leaving just one. + You can also specify the "all" option, which would + remove all of the points rather than leaving one. +
+
+ RADIUS + The radius filter is designed to include points based + on their proximity to a central point. Distances and the + central point are declared on the command line by passing the + , + , and + options to + the filter. Distance options may be expressed in miles + () or + kilometers (). The default is + zero miles. Additionally, the exclude option may be + specified to reverse the effect of the filter, so that points + further from the center are kept and closer points are + discarded. + + Using radius filter to identify points close to a given point + gpsbabel -i geo -f 1.loc \ + -x radius,distance=1.5M,lat=30.0,lon=-90.0 \ + -o mapsend \ + -F 2.wpt + + would include only points within 1.5 miles of N30.000 + W90.000 + +
+
+ DUPLICATE + The duplicate filter is designed to remove duplicate + points based on their shortname (traditionally a waypoint's + name on the GPS receiver), and/or their location (to a + precision of 6 decimals). This filter supports two options + that specify how duplicates will be recognized, "shortname" and "location". Generally, at least + one of these options is REQUIRED. + + Using duplicate filter to suppress points with same name and locations + gpsbabel -i gpx -f 1.gpx -f 2.gpx -x duplicate,location,shortname \ + -o gpx -F merged_with_no_dupes.gpx + + would remove points that have duplicate shortnames + *AND* duplicate locations. The result would be a GPX file + that more than likely contains only unique points and point + data. + The duplicate filter can also take an "all" option. + If you specify that option, all instances of a duplicated + waypoint will be removed, not just the second and subsequent + instances. If your input file contains waypoints A, B, B, + and C, the output file will contain waypoints A, B, and C + without the "all" option, or just A and C with the "all" + option. This option can be useful as an "ignore list" in + some circumstances. + + Finally, the duplicate filter takes a + "" option. If you specify that + option, the latitude and longitude frmo later duplicates will + replace the latitude and longitude in earlier waypoints. You + can use this to apply a list of "waypoint corrections" to a larger + file, while keeping all of the other details from the larger + file. +
+
+ DISTANCE FROM A ROUTE (ARC) ARC + The arc filter is designed to include points based on + their proximity to an arc, which is a series of connected + line segments similar to a route or a track but without any + associated data other than the coordinates. + + The arc is defined in a file whose name must be + provided with the option to the filter. + That file contains pairs of coordinates for the vertices of + the arc, one coordinate pair per line. Comments may be + included by preceding them with a '#' character. An arc file + looks something like this sample: + + +# Lima Road/SR3 north of Fort Wayne, Indiana +41.150064468 -85.166207433 +41.150064468 -85.165371895 +41.149034500 -85.165157318 +41.147832870 -85.164771080 +41.146631241 -85.164384842 +41.144270897 -85.163655281 +41.141953468 -85.162882805 + An arc file may optionally contain gaps in the arc. You can + specify such a gap by inserting a line containing "#break" + either on a line by itself or after the coordinates of the + starting point of the new arc segment. + + In addition to the file containing the arc, you should + also specify the maximum distance from the arc that will be + accepted; that distance is declared on the command line with + the + option to the filter. Distance options may be expressed in + miles () or + kilometers (). The default is + zero miles. You may also specify the exclude option, which + causes GPSBabel to only include points that are further than + the specified distance from the arc. + + For example, assuming the arc above is in a file called lima_rd.txt: + gpsbabel -i geo -f 1.loc + -x arc,file=lima_rd.txt,distance=1 \ + -o mapsend -F 2.wpt + would include only points within one mile of the + section of Lima Road covered by the arc. +
+
+ POLYGON + The polygon filter includes points if they are inside + of a polygon. A polygon file looks like an arc file, except + that the arc it describes must be a closed cycle. That is, + for a simple polygon, the first and last points must be the + same. Here's a square: + + + # A square (not really) polygon + 41.0000 -85.0000 + 41.0000 -86.0000 + 42.0000 -86.0000 + 42.0000 -85.0000 + 41.0000 -85.0000 + + Polygons may include islands and holes. To specify an + island or a hole, just append it to the main polygon. + + As with the arc filter, you specify a polygon by + specifying the name of the file that contains it, using + the file option. You can also specify the exclude option, + which reverses the operation of the filter so that it only + includes points that are NOT in the polygon. + + Note that this filter currently will not work properly + if your polygon contains one or both poles or if it spans the + line of 180 degrees east or west longitude. + + For example, assume you have a polygon file that + defines the border of your county, called mycounty.txt. This + command line will give you only the points in your county: + + gpsbabel -i geo -f 1.loc -x polygon,file=mycounty.txt \ +-o mapsend -F 2.wpt +
+
+ SIMPLIFY + The Simplify filter is used to simplify routes and + tracks for use with formats that limit the number of points + they can contain or just to reduce the complexity of a route. + The Simplify filter attempts to remove points from each + route until the number of points or the error is within the given + bounds, while also attempting to preserve the shape of the original + route as much as possible. + You must specify either the "count" option or the "error" option. + The count option requires a number, which is the maximum number + of points that will appear in the simplified track. The error + option takes a distance, optionally followed by an 'm' for miles or + a 'k' for kilometers. That distance specifies the maximum error; + how that error is determined depends on the simplification method, + described next. + You may also specify the method by which the filter chooses + which points to remove. The options are "length", which tries to + remove points that have the smallest effect on the overall length + of the route, or "crosstrack", which tries to remove points that + have the smallest overall effect on the shape of the route. The + default, if you don't specify either option, is "crosstrack". + The quality of the results will vary depending on the + density of points in the original route and the length of the + original route. + For example, suppose you have a route from Street + Atlas 2003 that you wish to use with a Magellan GPS receiver + that only supports up to 50 points in a route: + gpsbabel -r -i saroute -f RoadTrip.anr \ + -x simplify,count=50 \ + -o magellan -F grocery.rte + +
+
+ REVERSE + The reverse filter is used to reverse tracks and routes. + It's mostly useful for those few formats where track/route + sequence matters and there isn't a way to reverse them using + the program itself. + The reversal is performed in the laziest way possible. + Timestamps are kept with the original waypoints so the + resulting track or route will have the interesting + characteristic that time runs backwards. This tends to make + Magellan Mapsend, in particular, do a wierd thing and place + each waypoint on a separate day. + + Additionally, if you're using this to reverse a route + that navigates, say, an exit ramp or a one way street, you + will be in for unpleasant ride. application cares about + timestamps + +
+
+ SORT + This simple filter allows you to alphabetize waypoints + by shortname or by description. It has a special suboption + (gcid) to sort by geocaching.com waypoint ID's when the input + comes from a GPX file that has GC numbers in it. + +
+
+ STACK + This filter is designed to solve advanced problems + that involve shuffling multiple lists of waypoints. It has + three distinct sets of suboptions: + PUSH + Pushes the current list of waypoints onto the stack. + If the 'copy' suboption is specified, a copy of the current + list is pushed onto the stack; otherwise, the current list is + cleared. + +-x stack,push +-x stack,push,copy + + POP + 'Pops' the top list of waypoints off of the stack. + What is done with that list depends on the suboption + specified. If the 'append' suboption is specified, the top + list of waypoints from the stack is added to the end of the + current list of waypoints. If the 'discard' option is + specified, the top list of waypoints is removed from the + stack and discarded, leaving the current list of waypoints + unchanged. If the 'replace' option is specified, or if no + option is specified, the top list of waypoints from the stack + replaces the current list of waypoints; the previous contents + of the current list are discarded. + +-x stack,pop +-x stack,pop,discard +-x stack,pop,append + + SWAP + Swaps the current list of waypoints with a list from + the stack. If no further options are specified, the current + list is swapped with the top list on the stack. If the + 'depth' option is specified, it indicates which item on the + stack should be swapped. + +-x stack,swap +-x stack,swap,depth=2 + + The stack can be used in conjunction with other + filters to implement a "union" or "logical or" functionality. + The basic idea is to use the stack to store copies of the + original list of waypoints, then use the 'swap' function to + replace each copy with a filtered list. Finally, append all + of the filtered lists to create one big list, which is then + output. The following example finds a list of all points + that are either inside county A or inside county B. Any + points that are inside both counties are duplicated (but the + duplicates can be removed with the DUPLICATE filter; see + above.) + + +gpsbabel -i gpx -f in.gpx \ + -x stack,push,copy \ + -x polygon,file=county_a.txt \ + -x stack,swap \ + -x polygon,file=county_b.txt \ + -x stack,pop,append \ + -o gpx -F out.gpx + + This example reads a large list of waypoints and + extracts the points within 20 miles of each of two cities, + writing the waypoint descriptions into two different PalmDoc + files and exporting all of the points to the GPS receiver: + + +gpsbabel -i gpx -f indiana.gpx \ + -x stack,push,copy \ + -x radius,lat=41.0765,lon=-85.1365,distance=20m \ + -o palmdoc,dbname=Fort\ Wayne -F fortwayne.pdb \ + -x stack,swap \ + -x radius,lat=39.7733,lon=-86.1433,distance=20m \ + -o palmdoc,dbname=Indianapolis -F indianapolis.pdb \ + -x stack,pop,append \ + -o magellan -F fwaind.wpt + + +
+
+ TRACK + ( !!! This filter always drops empty tracks !!! ) + + The track filter is a tool for manipulating track lists. The +following options are available: + TITLE + Gives the new track(s) a basic title. Basic means if + more than one track is created by filter the title will be + expanded with the date the new track. Special formats (see + UNIX date or strftime for details) are possible. + + +gpsbabel -t \ + -i gpx -f in.gpx \ -x track,pack,split,title="ACTIVE LOG-%D" \ +-o gpx -F out.gpx PACK + + MOVE + Change the time of all trackpoints. This is useful if + your track has moved by one or more hours through a time zone + problem. The following example will shift your track to be + one hour later. + +gpsbabel -t -i gpx -f in.gpx \ + -x track,move=+1h,pack,title="ACTIVE LOG" \ + -o gpx -F out.gpx + START / STOP + Filter tracks against time borders. All points outside + this range will be dropped. The date-time paramters have to + be in form of YYYYMMDDHHMMSS; but you may specify only the + most significant portion represented in the the leftmost + fields. See the example, where the time is specified only + through the hour. If you only want to get a track mapped on + 20 july 2005 from 10 am to 6pm, you should use this: + +gpsbabel -t -i gpx -f in.gpx -x \ + track,start=2005072010,stop=2005072018 \ + -o gpx -F out.gpx + PACK + With this default option all tracks from input will be + packed into one track. If tracks overlaps in time, the filter + stops working. To pack all the tracks together into one + track and give it a name, use this: + +gpsbabel -t -i gpx -f in.gpx -x track,pack,title="ACTIVE LOG" \ + -o gpx -F out.gpx + SPLIT + The input track will be split into several tracks + depending on date of track points. If there is more than one + track, use the pack option before before using this. To + split a single tracks into separate tracks for each day and + name them, use this: + + +gpsbabel -t -i gpx -f in.gpx -x \ + track,split,title="ACTIVE LOG \ + # %Y%m%d" -o gpx -F out.gpx + If the input has multiple tracks, pack them together before +splitting them back apart per day thusly: + +gpsbabel -t -i gpx -f in.gpx \ + -x track,pack,split,title="ACTIVE LOG # %D" \ + -o gpx -F out.gpx + Additionally you can add an interval to the split + option. With this the track will be split if the time + between two points is greater than this parameter. The + interval must be numeric and can be int days, hours, minutes + or seconds, expressed as one of the character "d", "h", "m", + or "s". If no trailing character is present, the units are + assumed to be in seconds. + + For example, to split a track based on an four hour + interval, use this: + +gpsbabel -t \ + -i gpx -f in.gpx \ + -x track,pack,split=4h,title="LOG # %c" \ + -o gpx -F out.gpx + + MERGE + Merge puts all track points into one single track and + sort them by time. Points with identical time stamp will be + dropped !!! + If you want to merge tracks from different devices but + from same trip, use this: + +gpsbabel -t \ + -i gpx -f john.gpx \ + -i gpx -f doe.gpx \ + -x track,merge,title="COMBINED LOG" \ + -o gpx -F john_doe.gpx + + FIX + Fix forces the GPS fix status for all trackpoints to the + specified value. The value may be PPS, DGPS, 3D, 2D, or NONE. + + + gpsbabel -i gpx -f trk.gpx -x track,fix=3D -o nmea -F - + + + COURSE + Course computes a value for the GPS heading at each trackpoint. + This is most useful with trackpoints from formats that don't support + heading information or for trackpoints synthesized by the interpolate + filter. The heading at each trackpoint is simply the course from the + previous trackpoint in the track. The first trackpoint in each track + is arbitrarily assigned a heading of 0 degrees. + + gpsbabel -i gpx -f trk.gpx -x track,course,speed -o nmea -F - + + + SPEED + Course computes a value for the GPS speed at each trackpoint. + This is most useful with trackpoints from formats that don't support + speed information or for trackoints synthesized by the interpolate + filter. The speed at each trackpoint is the average speed from the + previous trackpoint (distance/time). The first trackpoint in each + track is assigned a speed of "unknown." + + gpsbabel -i gpx -f trk.gpx -x track,course,speed -o nmea -F - + + +
+
+ DISCARD + This filter 'fixes' gps data by discarding points with + a hdop and/or vdop over a set limit. If you give both the + hdop and a vdop options, by default points that exceed EITHER + are discarded (OR). This filter processes waypoints, tracks, + and routes. + + HDOP (float) + Points with a hdop exceeding the given value are + discarded. + + VDOP (float) + Points with a vdop exceeding the given value are + discarded. + HDOPANDVDOP + Only useful if both hdop and vdop are given. Now + logical AND is used, i.e. only points exceeding both given + values are discarded. + + Example: + gpsbabel \ + -i gpx -f in.gpx \ + -x discard,hdop=10,vdop=20,hdopandvdop \ + -o gpx -F out.gpx + + Contributed by Tobias Minich. +
+
+ NUKETYPES + + There are three main types of data that GPSBabel deals with: + waypoints, tracks, and routes. The nuketypes filter allows + removing all the data of any or all of those three types. + + - Removes all waypoints. + - Removes all routes. + - Removes all routes. + + For example, if you have a GPX file that contains routes, tracks, and + waypoints and you want a GPX file that contains only tracks, + you can use this filter to remove the waypoints with this command: + + gpsbabel -i gpx -f bigfile.gpx -x nuketypes,waypoints,routes -o gpx -F tracksonly.gpx + +
+
+ INTERPOLATE + + This filter modifies any tracks so that either the distance or the time + between consecutive points is no less than the specified interval. Where + points are missing, the filter fills them in by following a straight + line (actually a great circle) between the adjacent points. You + must specify either the "distance" or the "time" option. + + gpsbabel -i gpx -f track.gpx -x interpolate,time=10 -o gpx -f newtrack.gpx + Reads track.gpx and inserts points wherever two adjacent + trackpoints are more than 10 seconds apart + gpsbabel -i gpx -f track.gpx -x interpolate,distance=15k -o gpx -f newtrack.gpx + Reads track.gpx and inserts points wherever two adjacent + trackpoints are more than 15 kilometers apart + gpsbabel -i gpx -f track.gpx -x interpolate,distance=2m -o gpx -f newtrack.gpx + Reads track.gpx and inserts points wherever two adjacent + trackpoints are more than 2 miles apart +
+ + +
+
diff --git a/xmldoc/readme.xml b/xmldoc/readme.xml new file mode 100644 index 000000000..2115729dc --- /dev/null +++ b/xmldoc/readme.xml @@ -0,0 +1,20 @@ + + + + %parts; + + %chaps; +] +> + + + + GPSBabel Documentation + + + &allchapters; + + diff --git a/xmlgeneric.c b/xmlgeneric.c index f9877da1f..edd478f4c 100644 --- a/xmlgeneric.c +++ b/xmlgeneric.c @@ -21,8 +21,9 @@ #include "defs.h" #include "xmlgeneric.h" +#include "cet_util.h" -#ifndef NO_EXPAT +#if HAVE_LIBEXPAT #include static XML_Parser psr; #endif @@ -31,6 +32,7 @@ static vmem_t current_tag; static vmem_t cdatastr; static FILE *ifd; static xg_tag_mapping *xg_tag_tbl; +static const char **xg_ignore_taglist; #define MY_CBUF 4096 @@ -39,7 +41,14 @@ static xg_tag_mapping *xg_tag_tbl; void write_xml_header(FILE *ofd) { - fprintf(ofd, "\n"); + char buff[128]; + cet_cs_vec_t *cs = cet_find_cs_by_name(CET_CHARSET_ASCII); + + if ((global_opts.charset != NULL) && (global_opts.charset != cs)) + snprintf(buff, sizeof(buff), " encoding=\"%s\"", global_opts.charset_name); + else + buff[0] = 0; + fprintf(ofd, "\n", buff); } void @@ -96,8 +105,10 @@ xml_fill_in_time(char *time_string, const time_t timep, int long_or_short) struct tm *tm = gmtime(&timep); char *format; - if (!tm) + if (!tm) { + *time_string = 0; return; + } if (long_or_short == XML_LONG_TIME) format = "%02d-%02d-%02dT%02d:%02d:%02dZ"; @@ -117,11 +128,13 @@ xml_write_time(FILE *ofd, const time_t timep, char *elname) { char time_string[64]; xml_fill_in_time(time_string, timep, XML_LONG_TIME); - fprintf(ofd, "<%s>%s\n", - elname, - time_string, - elname - ); + if (time_string[0]) { + fprintf(ofd, "<%s>%s\n", + elname, + time_string, + elname + ); + } } @@ -147,13 +160,42 @@ xml_tbl_lookup(const char *tag, xg_cb_type cb_type) return NULL; } +/* + * See if tag element 't' is in our list of things to ignore. + * Returns 0 if it is not on the list. + */ +static int +xml_consider_ignoring(const char *t) +{ + const char **il; + + if (!xg_ignore_taglist) { + return 0; + } + + for (il = xg_ignore_taglist; *il; il++) { + if (0 == strcmp(*il, t)) { + return 1; + } + } + return 0; +} + static void -xml_start(void *data, const char *el, const char **attr) +xml_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { char *e; char *ep; xg_callback *cb; + const char *el; + const char **attrs; + + el = xml_convert_to_char_string(xml_el); + attrs = xml_convert_attrs_to_char_string(xml_attr); + + if (xml_consider_ignoring(el)) + return; vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); @@ -166,28 +208,36 @@ xml_start(void *data, const char *el, const char **attr) cb = xml_tbl_lookup(e, cb_start); if (cb) { - (*cb)(NULL, attr); + (*cb)(NULL, attrs); } + xml_free_converted_string(el); + xml_free_converted_attrs(attrs); } +#if HAVE_LIBEXPAT static void -xml_cdata(void *dta, const XML_Char *s, int len) +xml_cdata(void *dta, const XML_Char *xml_s, int len) { char *estr; - xg_callback *cb; + const char *s = xml_convert_to_char_string_n(xml_s, &len); vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); estr = (char *) cdatastr.mem + strlen(cdatastr.mem); memcpy(estr, s, len); estr[len] = 0; + xml_free_converted_string(s); } static void -xml_end(void *data, const char *el) +xml_end(void *data, const XML_Char *xml_el) { char *s = strrchr(current_tag.mem, '/'); + const char *el = xml_convert_to_char_string(xml_el); xg_callback *cb; + if (xml_consider_ignoring(el)) + return; + if (strcmp(s + 1, el)) { fprintf(stderr, "Mismatched tag %s\n", el); } @@ -201,6 +251,7 @@ xml_end(void *data, const char *el) (*cb)(el, NULL); } *s = 0; + xml_free_converted_string(el); } void xml_read(void) @@ -211,7 +262,7 @@ void xml_read(void) while ((len = fread(buf, 1, sizeof(buf), ifd))) { if (!XML_Parse(psr, buf, len, feof(ifd))) { fatal(MYNAME ":Parse error at %d: %s\n", - XML_GetCurrentLineNumber(psr), + (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); } } @@ -224,12 +275,17 @@ void xml_readstring( char *str ) int len = strlen(str); if (!XML_Parse(psr, str, len, 1)) { fatal( MYNAME ":Parse error at %d: %s\n", - XML_GetCurrentLineNumber(psr), + (int) XML_GetCurrentLineNumber(psr), XML_ErrorString(XML_GetErrorCode(psr))); } XML_ParserFree(psr); } +void xml_ignore_tags(const char **taglist) +{ + xg_ignore_taglist = taglist; +} + void xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) { @@ -250,6 +306,7 @@ xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) xg_tag_tbl = tbl; + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); XML_SetElementHandler(psr, xml_start, xml_end); XML_SetCharacterDataHandler(psr, xml_cdata); } @@ -263,6 +320,27 @@ xml_deinit(void) fclose(ifd); ifd = NULL; } + xg_ignore_taglist = NULL; +} +#else /* HAVE_LIBEXPAT */ +void +xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) +{ + fatal("This format does not support reading XML files as libexpat was not present."); } +void xml_read(void) +{ +} + +void xml_deinit(void) +{ +} + +void xml_readstring(char *unused) +{ +} + +#endif /* HAVE_LIBEXPAT */ + /******************************************/ diff --git a/xmlgeneric.h b/xmlgeneric.h index 1042766c2..ecfa68dd7 100644 --- a/xmlgeneric.h +++ b/xmlgeneric.h @@ -53,6 +53,7 @@ void xml_write_time(FILE *ofd, const time_t timep, char *elname); void xml_fill_in_time(char *time_string, const time_t timep, int long_or_short); void write_xml_header(FILE *ofd); +void xml_ignore_tags(const char **taglist); void xml_init(const char *fname, xg_tag_mapping *tbl,const char *encoding); void xml_read(void); diff --git a/xmltag.c b/xmltag.c index 992ec4871..50c4a46ee 100644 --- a/xmltag.c +++ b/xmltag.c @@ -96,6 +96,25 @@ void copy_xml_tag( xml_tag **copy, xml_tag *src, xml_tag *parent ) { copy_xml_tag( &(res->child), src->child, res ); } +static void +convert_xml_tag( xml_tag *tag ) { + char **ap = NULL; + + if (tag == NULL) return; + + tag->cdata = cet_convert_string(tag->cdata); + tag->parentcdata = cet_convert_string(tag->parentcdata); + + ap = tag->attributes; + while (*ap) + { + *ap = cet_convert_string(*ap); + ap++; + } + convert_xml_tag(tag->sibling); + convert_xml_tag(tag->child); +} + fs_xml *fs_xml_alloc( long type ); void fs_xml_destroy( void *fs ) { @@ -117,6 +136,12 @@ void fs_xml_copy( void **copy, void *source ) { copy_xml_tag( &(((fs_xml *)(*copy))->tag), src->tag, NULL ); } +void fs_xml_convert( void *fs ) { + fs_xml *xml = (fs_xml *)fs; + if ( xml ) { + convert_xml_tag( xml->tag ); + } +} fs_xml *fs_xml_alloc( long type ) { fs_xml *result = NULL; @@ -125,7 +150,7 @@ fs_xml *fs_xml_alloc( long type ) { result->fs.type = type; result->fs.copy = fs_xml_copy; result->fs.destroy = fs_xml_destroy; + result->fs.convert = fs_xml_convert; return result; } - diff --git a/yahoo.c b/yahoo.c new file mode 100644 index 000000000..8a98668fd --- /dev/null +++ b/yahoo.c @@ -0,0 +1,119 @@ +/* + Read Yahoo Geocoded files. + + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "xmlgeneric.h" + +static waypoint *wpt_tmp; +static char *as; + +#define MYNAME "yahoo" + +static +arglist_t yahoo_args[] = { + {"addrsep", &as, + "String to separate concatenated address fields (default=\", \")", + ", ", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static xg_callback wpt_s, wpt_lat, wpt_lon, wpt_e; +static xg_callback wpt_addr /*, wpt_city, wpt_state, wpt_zip, wpt_country*/; + +static xg_tag_mapping gl_map[] = { + { wpt_s, cb_start, "/ResultSet/Result" }, + { wpt_lat, cb_cdata, "/ResultSet/Result/Latitude" }, + { wpt_lon, cb_cdata, "/ResultSet/Result/Longitude" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Address" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/City" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/State" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Zip" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Country" }, + { wpt_e, cb_end, "/ResultSet/Result" }, + { NULL, 0, NULL} +}; + +static void +yahoo_rd_init(const char *fname) +{ + xml_init(fname, gl_map, NULL); +} + +static void +yahoo_read(void) +{ + xml_read(); +} + +static void +yahoo_rd_deinit(void) +{ + xml_deinit(); +} + +static void +yahoo_wr_init(const char *fname) +{ + fatal("Writing file of type %s is not supported\n", MYNAME); +} + +void wpt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); +} + +void wpt_e(const char *args, const char **unused) +{ + waypt_add(wpt_tmp); + wpt_tmp = NULL; +} + +void wpt_lat(const char *args, const char **unused) +{ + wpt_tmp->latitude = atof(args); +} + +void wpt_lon(const char *args, const char **unused) +{ + wpt_tmp->longitude = atof(args); +} + +void wpt_addr(const char *args, const char **unused) +{ + if (wpt_tmp->notes) { + wpt_tmp->notes = xstrappend(wpt_tmp->notes, as); + } + wpt_tmp->notes = xstrappend(wpt_tmp->notes, args); +} + +ff_vecs_t yahoo_vecs = { + ff_type_file, + { ff_cap_read }, + yahoo_rd_init, + yahoo_wr_init, + yahoo_rd_deinit, + NULL, + yahoo_read, + NULL, + NULL, + yahoo_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/zlib/ChangeLog b/zlib/ChangeLog new file mode 100644 index 000000000..1724324fb --- /dev/null +++ b/zlib/ChangeLog @@ -0,0 +1,860 @@ + + ChangeLog file for zlib + +Changes in 1.2.3.f-GPSBabel (17 July 2006) +- Change ZLIB_VERSION to "1.2.3.f-GPSBabel" and ZLIB_VERNUM to 0x123f +- When pathname is "-" assign stdin or stdout to [gzfile]->file (gzio.c/gz_open) +- WIN32 target: Add missing "b" to file open mode (gzio.c/gz_open) + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Added zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id: ChangeLog,v 1.1 2006/07/22 20:34:06 oliskoli Exp $. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/zlib/FAQ b/zlib/FAQ new file mode 100644 index 000000000..441d910da --- /dev/null +++ b/zlib/FAQ @@ -0,0 +1,339 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. + See the file win32/DLL_FAQ.txt in the zlib distribution. + Pointers to the precompiled DLL are found in the zlib web site at + http://www.zlib.org. + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact us (zlib@gzip.org). Examples of zlib usage are in the files + example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to it. + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . + To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip + formats use the same compressed data format internally, but have different + headers and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about + a single file, such as the name and last modification date. The zlib + format on the other hand was designed for in-memory and communication + channel applications, and has a much more compact header and trailer and + uses a faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode + the gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's Init functions allow + for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + It should. It has been tested on 64-bit machines, and has no dependence + on any data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format + than does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically + use Z_FULL_FLUSH, carefully write all the pending data at those points, + and keep an index of those locations, then you can start decompression + at those points. You have to be careful to not use Z_FULL_FLUSH too + often, since it can significantly degrade compression. + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + We don't know for sure. We have heard occasional reports of success on + these systems. If you do use it on one of these, please provide us with + a report, instructions, and patches that we can reference when we get + these questions. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at + to understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit + only if the compiler's "long" type is 32 bits. If the compiler's "long" + type is 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib + is compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of a 4K string space, other than the caller of + gzprintf() assuring that the output will not exceed 4K. On the other + hand, if zlib is compiled to use snprintf() or vsnprintf(), which should + normally be the case, then there is no vulnerability. The ./configure + script will display warnings if an insecure variation of sprintf() will + be used by gzprintf(). Also the zlibCompileFlags() function will return + information on what variant of sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://www.zlib.org/ + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly. So now, we simply make sure that the code always + works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of + deflate is not affected. This only started showing up recently since + zlib 1.2.x uses malloc() by default for allocations, whereas earlier + versions used calloc(), which zeros out the allocated memory. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very weak + and can be broken with freely available programs. To get strong encryption, + use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. + For PKZIP compatible "encryption", look at http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion + with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specficiation in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. + In any case, the compression improvements are so modest compared to other + more modern approaches, that it's not worth the effort to implement. + +41. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/zlib/Makefile.in.zlib b/zlib/Makefile.in.zlib new file mode 100644 index 000000000..2fd6e45c4 --- /dev/null +++ b/zlib/Makefile.in.zlib @@ -0,0 +1,154 @@ +# Makefile for zlib +# Copyright (C) 1995-2005 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# The call of configure is optional if you don't have special requirements +# If you wish to build zlib as a shared library, use: ./configure -s + +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +LDFLAGS=libz.a +LDSHARED=$(CC) +CPP=$(CC) -E + +LIBS=libz.a +SHAREDLIB=libz.so +SHAREDLIBV=libz.so.1.2.3 +SHAREDLIBM=libz.so.1 + +AR=ar rc +RANLIB=ranlib +TAR=tar +SHELL=/bin/sh +EXE= + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infback.o inftrees.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +all: example$(EXE) minigzip$(EXE) + +check: test +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +$(SHAREDLIBV): $(OBJS) + $(LDSHARED) -o $@ $(OBJS) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) + +example$(EXE): example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip$(EXE): minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +install: $(LIBS) + -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi + -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi + -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi + -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi + cp zlib.h zconf.h $(includedir) + chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h + cp $(LIBS) $(libdir) + cd $(libdir); chmod 755 $(LIBS) + -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 + cd $(libdir); if test -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIB) $(SHAREDLIBM); \ + ln -s $(SHAREDLIBV) $(SHAREDLIB); \ + ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ + (ldconfig || true) >/dev/null 2>&1; \ + fi + cp zlib.3 $(man3dir) + chmod 644 $(man3dir)/zlib.3 +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +uninstall: + cd $(includedir); \ + cd $(libdir); rm -f libz.a; \ + if test -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ + fi + cd $(man3dir); rm -f zlib.3 + +mostlyclean: clean +clean: + rm -f *.o *~ example$(EXE) minigzip$(EXE) \ + libz.* foo.gz so_locations \ + _match.s maketree contrib/infback9/*.o + +maintainer-clean: distclean +distclean: clean + cp -p Makefile.in Makefile + cp -p zconf.in.h zconf.h + rm -f .DS_Store + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/zlib/README b/zlib/README new file mode 100644 index 000000000..758cc5002 --- /dev/null +++ b/zlib/README @@ -0,0 +1,125 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.3 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install". For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.3 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be + installed before testing (do "make install" before "make test"), since the + library location is specified in the library. + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/zlib/README.gpsbabel b/zlib/README.gpsbabel new file mode 100644 index 000000000..08f223ab8 --- /dev/null +++ b/zlib/README.gpsbabel @@ -0,0 +1,3 @@ +Subset of zlib-1.2.3. All changes we made within the GPSBabel source +tree are documented in ChangeLog. + diff --git a/zlib/adler32.c b/zlib/adler32.c new file mode 100644 index 000000000..847a20dfd --- /dev/null +++ b/zlib/adler32.c @@ -0,0 +1,149 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: adler32.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/zlib/algorithm.txt b/zlib/algorithm.txt new file mode 100644 index 000000000..b022dde31 --- /dev/null +++ b/zlib/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/zlib/compress.c b/zlib/compress.c new file mode 100644 index 000000000..7ef8d6e5e --- /dev/null +++ b/zlib/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: compress.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/zlib/crc32.c b/zlib/crc32.c new file mode 100644 index 000000000..1b7bd1a06 --- /dev/null +++ b/zlib/crc32.c @@ -0,0 +1,423 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id: crc32.c,v 1.1 2006/07/22 20:34:06 oliskoli Exp $ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/zlib/crc32.h b/zlib/crc32.h new file mode 100644 index 000000000..8053b6117 --- /dev/null +++ b/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/zlib/deflate.c b/zlib/deflate.c new file mode 100644 index 000000000..3babea592 --- /dev/null +++ b/zlib/deflate.c @@ -0,0 +1,1736 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id: deflate.c,v 1.1 2006/07/22 20:34:07 oliskoli Exp $ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/zlib/deflate.h b/zlib/deflate.h new file mode 100644 index 000000000..78449ca42 --- /dev/null +++ b/zlib/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: deflate.h,v 1.1 2006/07/22 20:34:07 oliskoli Exp $ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/zlib/empty.in b/zlib/empty.in new file mode 100644 index 000000000..e69de29bb diff --git a/zlib/gzio.c b/zlib/gzio.c new file mode 100644 index 000000000..13f73cd11 --- /dev/null +++ b/zlib/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id: gzio.c,v 1.3 2006/08/13 17:08:00 oliskoli Exp $ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/zlib/infback.c b/zlib/infback.c new file mode 100644 index 000000000..455dbc9ee --- /dev/null +++ b/zlib/infback.c @@ -0,0 +1,623 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->write = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + + /* process literal */ + if (this.op == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/zlib/inffast.c b/zlib/inffast.c new file mode 100644 index 000000000..bbee92ed1 --- /dev/null +++ b/zlib/inffast.c @@ -0,0 +1,318 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/zlib/inffast.h b/zlib/inffast.h new file mode 100644 index 000000000..1e88d2d97 --- /dev/null +++ b/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/zlib/inffixed.h b/zlib/inffixed.h new file mode 100644 index 000000000..75ed4b597 --- /dev/null +++ b/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/zlib/inflate.c b/zlib/inflate.c new file mode 100644 index 000000000..792fdee8e --- /dev/null +++ b/zlib/inflate.c @@ -0,0 +1,1368 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/zlib/inflate.h b/zlib/inflate.h new file mode 100644 index 000000000..07bd3e78a --- /dev/null +++ b/zlib/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/zlib/inftrees.c b/zlib/inftrees.c new file mode 100644 index 000000000..8a9c13ff0 --- /dev/null +++ b/zlib/inftrees.c @@ -0,0 +1,329 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)1; + this.val = (unsigned short)0; + *(*table)++ = this; /* make a table to force an error */ + *(*table)++ = this; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/zlib/inftrees.h b/zlib/inftrees.h new file mode 100644 index 000000000..b1104c87e --- /dev/null +++ b/zlib/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/zlib/trees.c b/zlib/trees.c new file mode 100644 index 000000000..7a66ddaa8 --- /dev/null +++ b/zlib/trees.c @@ -0,0 +1,1219 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id: trees.c,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) + deflate_state *s; +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/zlib/trees.h b/zlib/trees.h new file mode 100644 index 000000000..72facf900 --- /dev/null +++ b/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/zlib/uncompr.c b/zlib/uncompr.c new file mode 100644 index 000000000..cf608299d --- /dev/null +++ b/zlib/uncompr.c @@ -0,0 +1,61 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: uncompr.c,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/zlib/zconf.h b/zlib/zconf.h new file mode 100644 index 000000000..58af16be8 --- /dev/null +++ b/zlib/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.h,v 1.1 2006/07/22 20:34:08 oliskoli Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/zlib/zconf.in.h b/zlib/zconf.in.h new file mode 100644 index 000000000..7c70c966d --- /dev/null +++ b/zlib/zconf.in.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.in.h,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/zlib/zlib.3 b/zlib/zlib.3 new file mode 100644 index 000000000..90b816287 --- /dev/null +++ b/zlib/zlib.3 @@ -0,0 +1,159 @@ +.TH ZLIB 3 "18 July 2005" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later +and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I example.c +and +.IR minigzip.c . +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source, +and are concerned primarily with bug fixes and portability enhancements. +.LP +A Java implementation of +.I zlib +is available in the Java Development Kit 1.1: +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmqs@cpan.org), +is available at CPAN (Comprehensive Perl Archive Network) sites, +including: +.IP +http://www.cpan.org/modules/by-module/Compress/ +.LP +A Python interface to +.IR zlib , +written by A.M. Kuchling (amk@magnet.com), +is available in Python 1.5 and later versions: +.IP +http://www.python.org/doc/lib/module-zlib.html +.LP +A +.I zlib +binding for +.IR tcl (1), +written by Andreas Kupries (a.kupries@westend.com), +is availlable at: +.IP +http://www.westend.com/~kupries/doc/trf/man/man.html +.LP +An experimental package to read and write files in .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/unzip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +web site. +.SH "SEE ALSO" +The +.I zlib +web site can be found at either of these locations: +.IP +http://www.zlib.org +.br +http://www.gzip.org/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) +.br +http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) +.br +http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.LP +Mark Nelson (markn@ieee.org) wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://dogma.net/markn/articles/zlibtool/zlibtool.htm +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://www.gzip.org/zlib/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS +Version 1.2.3 +Copyright (C) 1995-2005 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/zlib/zlib.h b/zlib/zlib.h new file mode 100644 index 000000000..a4431229e --- /dev/null +++ b/zlib/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3.f-GPSBabel" +#define ZLIB_VERNUM 0x123f + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/zlib/zutil.c b/zlib/zutil.c new file mode 100644 index 000000000..5f50b2471 --- /dev/null +++ b/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zutil.c,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/zlib/zutil.h b/zlib/zutil.h new file mode 100644 index 000000000..2045fda8a --- /dev/null +++ b/zlib/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: zutil.h,v 1.1 2006/07/22 20:34:11 oliskoli Exp $ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ -- 2.30.2